美文网首页
Controller优化1:统一Json格式响应定义

Controller优化1:统一Json格式响应定义

作者: 最爱下雨天呢 | 来源:发表于2020-03-11 22:21 被阅读0次

1 统一定义Json响应体{ code msg data}

通常情况我们在Controller层进行返回数据时候,对具体的业务数据要再次包装一下返回,如:

{
    "code":"0",
    "msg" :"success",
    "data":{}
}
  • code 状态码,如成功默认"0",失败默认"-1"
  • msg 状态码对应的提示信息
  • data 业务数据,成功有数据时填充。如成功无数据、失败状态 只有 codemsg

为此我们在Controller层进行一层封装ResponseJson.java,该类采用继承HashMap形式进行封装:


/**
 * 返回体封装,以json格式返回,包括 code msg data等信息
 *
 * @author jockeys
 * @since 2020/3/11
 */
public final class ResponseJson extends HashMap<String, Object> {
    /**
     * 默认错误码
     */
    private static final String DEFAULT_ERROR_CODE = "-1";

    /**
     * 默认构造函数私有化
     */
    private ResponseJson() {
        put("code", ResponseEnum.SUCCESS.getCode());
        put("msg", ResponseEnum.SUCCESS.getMessage());
    }

    /**
     * 重新设置提示信息
     *
     * @param msg 提示信息
     * @return this object
     */
    public ResponseJson setMsg(String msg) {
        this.put("msg", msg);
        return this;
    }

    /**
     * 错误-消息返回体设置
     *
     * @param code 错误状态码
     * @param msg  错误提示信息
     * @return this object
     */
    public static ResponseJson error(String code, String msg) {
        ResponseJson ans = new ResponseJson();
        ans.put("code", code);
        ans.put("msg", msg);
        return ans;
    }

    /**
     * 错误-消息返回体设置(默认错误状态码为 -1)
     *
     * @param msg 错误提示信息
     * @return this object
     */
    public static ResponseJson error(String msg) {
        return error(DEFAULT_ERROR_CODE, msg);
    }

    /**
     * 错误-信息返回体设置,默认错误码和错误提示
     *
     * @return this object
     */
    public static ResponseJson error() {
        return error(ResponseEnum.SERVER_ERROR.getCode(), ResponseEnum.SERVER_ERROR.getMessage());
    }

    /**
     * 错误-信息返回体设置,返回信息状态定义
     *
     * @return this object
     */
    public static ResponseJson error(ResponseEnum responseEnum) {
        return error(responseEnum.getCode(), responseEnum.getMessage());
    }

    /**
     * 成功-信息返回体设置
     *
     * @param data 响应数据
     * @return the object with response data
     */

    public static ResponseJson ok(Object data) {
        ResponseJson ans = new ResponseJson();
        ans.put("data", data);
        return ans;
    }

    /**
     * 成功-信息返回体设置 (无响应数据)
     *
     * @return this object without response data
     */
    public static ResponseJson ok() {
        return new ResponseJson();
    }

}

对于 code/ msg组成的键值对,我们用Enum进行定义(注意代码中使用了lombok插件):

/**
 * 返回码封装,用枚举类实现
 *
 * @author jockeys
 * @since 2020/3/11
 */
@Getter
@AllArgsConstructor
public enum ResponseEnum {
    /**
     * 成功状态码
     */
    SUCCESS("0", "success"),
    
    /**
     * 系统异常相关错误
     */
    SERVER_ERROR("-1", "未知异常,请联系管理员"),
    SYSTEM_ERROR("system-err", "系统内部错误,请联系管理员..."),
    NETWORK_ERROR("network-err", "网络故障,请检查网络连接..."),
    BUSINESS_ERROR("business-err", "业务处理中,请稍后重试..."),
    
    /**
     * 通用的校验错误
     */
    ILLEGAL_ARGS_ERROR("args-illegal-err", "非法参数错误"),
    ARGS_PASSWORD_WRONG("password-format-err", "密码格式不正确"), 
    ARGS_PHONE_WRONG("phone-format-err", "手机格式不正确"),
   ;   

    private String code;
    private String message;
}

接下来我们可以在Controller层中进行应用,e.g.

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
    
    @ApiOperation(value = "Swagger注释:包装体封装Json格式返回测试接口")
    @GetMapping("/hello")
    public ResponseJson sayHello() {
        log.info("进入方法...")
        String baby = "what’s happening to you?";         
        return ResponseJson.ok(baby);
    }
}

当然,上述步骤封装完毕后,我们已经能够正常使用进行统一的格式返回。

2 统一包装处理 @ResponseBodyAdvice

但是在Controller层所有的返回类型均为ResponseJson,我们在Controller层无法感知具体的业务含义,那我们为什么不能够将该步骤的封装在延后一下,在Http请求获得响应返回进行包装? 这当然是可行的!spring框架提供的ResponseBodyAdvice@ControllerAdvice可以用来实现这一想法。


@Slf4j
@ControllerAdvice
public class ResponseJsonFormatHandler implements ResponseBodyAdvice<Object> { 
   @Override
   public boolean supports(MethodParameter methodParameter,
                           Class<? extends HttpMessageConverter<?>> aClass) {
       // 判断请求是否需要包装,默认true
       return true;
   }

   @Override
   public Object beforeBodyWrite(Object o, MethodParameter methodParameter,
                                 MediaType mediaType,
                                 Class<? extends HttpMessageConverter<?>> aClass,
                                 ServerHttpRequest serverHttpRequest,
                                 ServerHttpResponse serverHttpResponse) {

       log.info("进入返回体重写过程,封装code msg data...");  
       return null == o? ResponseJson.ok():ResponseJson.ok(o);
   }
}

这样,我们Controller层代码就可以直接返回业务体

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {     
    @GetMapping("/hello")
    public String sayHello() {
        log.info("进入方法...")
        String baby = "what’s happening to you?";         
        return baby;
    }
}

下一篇:Controller优化2链接:统一Json格式返回(注解实现)

相关文章

网友评论

      本文标题:Controller优化1:统一Json格式响应定义

      本文链接:https://www.haomeiwen.com/subject/xfekjhtx.html