统一返回结果
"统一返回结果"泛指在前后端分离的开发中,后端开发人员一般会规定一个结果集,所有接口的返回值,统一使用这个结果集的形式返回至前端。
结果集拥有的信息
- success : 是否请求成功
- code : 状态码
- msg : 提示信息
- data : 携带数据
private Boolean success;
private Integer code;
private String message;
private Map<String, Object> data = new HashMap<String, Object>();
优化策略
(一) 固定Code值
- 定义常量
public static Integer SUCCESS = 200; // 成功
public static Integer ERROR = 500; // 失败
- 使用接口来定义常量,可以省去前面的public static
- 使用枚举
public enum Code{
NotFind(404),
Error(500),
Success(200);
private int code;
CodeEnum(Integer code) {
this.code = code;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}
(二) 使用静态工厂方法
首先我们将结果类的无参构造私有化,且不提供其他构造方法
private Result() {}
这样就杜绝了在外界创建本类的实例,然后使用静态工厂方法来生成本类的实例并返回
// 成功静态方法
public static Result ok() {
Result result = new Result();
result.setSuccess(true);
result.setCode(ResultCode.SUCCESS);
result.setMessage("成功");
return result;
}
// 失败静态方法
public static Result error() {
Result result = new Result();
result.setSuccess(false);
result.setCode(ResultCode.ERROR);
result.setMessage("失败");
return result;
}
当前的情况,我们可以比较方便的使用结果集这个类来响应前端的请求了,但是还存在一个问题,我们没办法设置或者修改静态工厂生成的实例中的属性值。
(三) 链式调用支持
为结果集类提供设置属性的方法,但是返回值必须为当前对象本身也就是this
public Result success(Boolean success){
this.setSuccess(success);
return this;
}
public Result message(String message){
this.setMessage(message);
return this;
}
public Result code(Integer code){
this.setCode(code);
return this;
}
public Result data(String key, Object value){
this.data.put(key, value);
return this;
}
public Result data(Map<String, Object> map){
this.setData(map);
return this;
}
分析和实际使用
先使用上述生成的结果集来响应一个失败的请求。
return Result.error().message("请求出错!").data("异常信息", "/ by zero")
让我们来分析一下上写法的套路
- 使用静态工厂方法error()生成Result类的实例并获取
- 使用获取的实例调用实例方法message()修改实例中属性,并再次返回该实例,形成链式调用
- 继续使用获取的实例调用data()修改实例属性,返回实例,继续链式
- ...
结语
对于不同的项目中,大伙的结果集处理方式肯定都是不尽相同的,上述也只是在学习过程中认识到的自我感觉比较方便的一种方案。用到了很多基础知识和理论,甚至还用静态工厂进行了解耦。果然有强迫症的我对于这种优雅的写代码方式毫无抵抗力+=.=+
Q.E.D.