• 【Spring AOP】统⼀数据返回格式


    为什么需要统一数据返回格式

    1. ⽅便前端程序员更好的接收和解析后端数据接⼝返回的数据。
    2. 降低前端程序员和后端程序员的沟通成本,按照某个格式实现就⾏了,因为所有接⼝都是这样返回的。
    3. 有利于项⽬统⼀数据的维护和修改。
    4. 有利于后端技术部⻔的统⼀规范的标准制定,不会出现稀奇古怪的返回内容。

    统一数据返回格式的实现

    1. 类上添加 @ControllerAdvice 注解表示对 Controller 的通知
    2. 实现 ResponseBodyAdvice 接口并重写 supports 和 beforeBodyWrite 方法, 拦截返回的数据, 并对数据格式进行重写
    @ControllerAdvice
    public class ResponseAdvice implements ResponseBodyAdvice {
    
    	@Resource
        private ObjectMapper objectMapper;
    
        /**
         * 内容是否需要重写(通过此⽅法可以选择性部分控制器和⽅法进⾏重写)
         * 返回 true 表示重写, 进入下面的 beforeBodyWrite 方法
         */
        @Override
        public boolean supports(MethodParameter returnType, Class converterType) {
            return true;
        }
        
        /**
         * ⽅法返回之前调⽤此⽅法
         */
        @SneakyThrows // 这个注解, 等价于 方法上加 Throws Exception
        @Override
        public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                      Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
            // 构造统⼀返回对象
            HashMap<String, Object> result = new HashMap<>();
            result.put("state", 1);
            result.put("msg", "");
            result.put("data", body);
            if (body instanceof String) {
                // 如果数据类型是 String 的话, 比较特殊, 需要 使用 jackson单独处理
                return objectMapper.writeValueAsString(request);
            }
            return result;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    统一数据返回格式举例

    假如说约定返回格式为一个类 AjaxResult

    /**
     *  统一数据返回格式
     *  实现 Serializable 接口支持序列化
     */
    @Data
    public class AjaxResult implements Serializable {
        // 状态码
        private Integer code;
        // 状态码描述信息
        private String msg;
        // 返回的数据
        private Object data;
    
        /**
         *  操作成功返回的结果
         */
        public static AjaxResult success(Object data) {
            AjaxResult result = new AjaxResult();
            result.setCode(200);
            result.setMsg("");
            result.setData(data);
            return result;
        }
    
        /**
         * 根据需要调用不同的重载的 方法
         */
        public static AjaxResult success(Integer code, Object data) {
            AjaxResult result = new AjaxResult();
            result.setCode(code);
            result.setMsg("");
            result.setData(data);
            return result;
        }
    
    
        public static AjaxResult success(Integer code, String msg, Object data) {
            AjaxResult result = new AjaxResult();
            result.setCode(code);
            result.setMsg(msg);
            result.setData(data);
            return result;
        }
    
        /**
         *  操作失败返回的结果
         */
        public static AjaxResult fail(Integer code, String msg) {
            AjaxResult result = new AjaxResult();
            result.setCode(code);
            result.setMsg(msg);
            result.setData(null);
            return result;
        }
    
    
        public static AjaxResult fail(Integer code, String msg, Object data) {
            AjaxResult result = new AjaxResult();
            result.setCode(code);
            result.setMsg(msg);
            result.setData(data);
            return result;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    拦截返回的数据, 对不满足条件的数据进行封装使满足格式.

    /**
     * 实现统一数据返回的保底类
     * 说明: 在返回数据之前, 检测数据的类型是否是统一的对象, 如果不是, 封装成统一的对象
     */
    
    @ControllerAdvice
    public class ResponseAdvice implements ResponseBodyAdvice {
    
        @Autowired
        private ObjectMapper objectMapper;
    
    
        /**
         * 开关, 如果是 true, 才会调用 beforeBodyWrite 方法
         */
        @Override
        public boolean supports(MethodParameter returnType, Class converterType) {
            return true;
        }
    
        /**
         * 对数据格式进行校验和封装
         */
        @SneakyThrows  // 这个注解, 等价于 方法上加 Throws Exception
        @Override
        public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
            if (body instanceof AjaxResult) {
            	// 本身格式就是 AjaxResult 了
                return body;
            }
            if (body instanceof String) {
                // 是字符串的话比较特殊, 需要使用 jackson
                return objectMapper.writeValueAsString(AjaxResult.success(body));
            }
            // 如果不是字符串, 直接返回对象即可
            return AjaxResult.success(body);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    好啦! 以上就是对 统⼀数据返回格式 的讲解,希望能帮到你 !
    评论区欢迎指正 !

  • 相关阅读:
    《闲着刷题》(1)--牛客python入门题
    【JVM技术专题】让你完全攻克内存溢出(OOM)这一难题「案例篇」
    python的PIL库
    计算机组成原理中的诸如4k*8位,8K*8位之类的是什么意思
    java计算机毕业设计校园网上跳蚤书市系统源码+mysql数据库+lw文档+系统+调试部署
    Linux namespace技术应用实践--调用宿主机命令(tcpdump/ip/ps/top)检查docker容器网络、进程状态
    简单易用的任务队列-beanstalkd
    桉木做的建筑模板质量评价
    进程间通信的六大方式
    如何把一个空项目变成SpringBoot项目
  • 原文地址:https://blog.csdn.net/m0_61832361/article/details/133797003