如何优雅的写Controller层代码

在开发一个基于MVC框架的web项目中,不可避免的要写Controller层,在Controller层中实现对请求值的解析以及封装返回值,每个接口在完成业务逻辑后将得到的结果传给前端,由前端完成页面渲染以及业务办理。整体看上去没什么问题,但是随着业务复杂度越来越高,如果不对每个接口的返回值作一些约束,那整个系统会变得越来越复杂,很难维护,这里我要介绍的就是如何优雅的统一处理Controller层的返回值,让整个项目的返回值变的统一易于维护和后期问题排查。
首先我们要定义一个统一的返回体,用于约定前后端处理值类型,可以这样来定义:


public class ResponseResult implements Serializable {
    private static final long serialVersionUID = 1L;

    private int code;

    private boolean success;

    private String message;

    private T value;
    }
    

其中个参数含义,code:响应值,success:请求是否成功响应;message:详细错误信息,value:则是返回值。
其中我们在定义code的时候可以设置一下枚举类,用于记录常规的一些接口返回失败码

public enum FailCodeEnum {

    PARAMS_ERROR(400, "请求参数错误"),

    SERVER_ERROR(500, "服务内部错误");

    private int code;
    private String message;

    FailCodeEnum(int errorCode, String message) {
        this.code = errorCode;
        this.message = message;
    }

这时候我们的Controller层代码可以写成这样:

@PostMapping(value = "save/{msgId}")
    public ResponseResult saveSms(@PathVariable(value = "msgId") String msgId, @RequestBody String body){
        log.info("== msgId: {}; body: {}", msgId, body);
        return new ResponseResult(System.currentTimeMillis());
    }

这样后端就会有一个统一的返回体了,但是这样每个接口都需要返回ResponseResult的方式对开发不怎么友好,我们可以对代码再进行优化。
通过@ControllerAdvice注解对Controller层的返回体作统一处理,我们的代码优化后如下:

@Slf4j
@ControllerAdvice
public class ResponseSupportAdvice implements ResponseBodyAdvice {

    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        ServletRequestAttributes request = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        Object testAtt = request.getAttribute(Consts.WARP_REQUEST, 0);
        log.info("class'name: {}, testAtt: {}", name, testAtt);
        return Boolean.parseString(testAtt);
    }

    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter,
            MediaType mediaType, Class aClass,
            ServerHttpRequest serverHttpRequest,
            ServerHttpResponse serverHttpResponse) {
        log.info("return value: {}", o.toString());
        return new ResponseResult<>(o);
    }

}

Controller层的代码优化如下了:

@PostMapping(value = "save/{msgId}")
    public Object saveSms(@PathVariable(value = "msgId") String msgId, @RequestBody String body){
        log.info("== msgId: {}; body: {}", msgId, body);
        // 设置请求值是否需要封装
        httpRequest.setAttribute(Consts.WARP_REQUEST, "true");
        return System.currentTimeMillis();
    }

这样就ok了,简单吧。到此返回的设计思路完成,是不是又简洁,又优雅。

你可能感兴趣的:(web权限控制,java,接口,spring)