统⼀数据返回格式快速⼊⻔

为什么会有统⼀数据返回?

其实统一数据返回是运用了AOP(对某一类事情的集中处理)的思维。
优点:

1.⽅便前端程序员更好的接收和解析后端数据接⼝返回的数据。

2.降低前端程序员和后端程序员的沟通成本,因为所有接⼝都是固定的返回格式。

3.有利于项⽬统⼀数据的维护和修改。

4.有利于后端技术部⻔的统⼀规范的标准制定。

代码实现

假如我们要统一返回Result 对象

复制代码
import lombok.Data;

@Data
public class Result<T> {

    private String s = "我是Result的s属性";
    private Integer num = 2008;
    private T data;

    public static <T> Result success(T data) {
        Result result = new Result<>();
        result.setData(data);
        return result;
    }
}

使用TextController进行测试

复制代码
import com.wh.advice.model.Result;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;


@RestController
public class TextController {

    @RequestMapping("/text1")
    public Integer text1() {
        return 100;
    }

    @RequestMapping(value = "/text2", produces = "application/json")
    public String text2() {
        return "text";
    }

    @RequestMapping("/text3")
    public Result<List<Integer>> text3() {
        List<Integer> list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        return Result.success(list);
    }
}

注意:

produces = "application/json"->表示将生产json格式的数据

统⼀的数据返回格式的实现

  1. 添加类注解@ControllerAdvice,实现接口ResponseBodyAdvice
  2. 重写responseAdvice方法
  3. 重写beforeBodyWriter方法

代码:

复制代码
import com.wh.advice.model.Result;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {


    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        return Result.success(body);
    }
}

1.supports⽅法: 判断是否要执⾏beforeBodyWrite⽅法. true为执⾏, false不执⾏. 通过该⽅法可以
选择哪些类或哪些⽅法的response要进⾏处理, 其他的不进⾏处理.

2.beforeBodyWrite⽅法: 对response⽅法进⾏具体操作处理 。

1.测试http://127.0.0.1:8080/text1

添加统⼀数据返回格式之前:

添加统⼀数据返回格式之后:

2.我们继续测http://127.0.0.1:8080/text2
结果显⽰, 发⽣内部错误

查看⽇志, ⽇志报错

多测试⼏种不同的返回结果, 发现只有返回结果为String类型时才有这种错误发⽣

解决问题:

我们要注入ObjectMapper

复制代码
@Autowired
private ObjectMapper objectMapper;

对 beforeBodyWrite⽅法进行修改:

复制代码
 @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof String) {
            return objectMapper.writeValueAsString(Result.success(body));
        }
        return Result.success(body);
    }

3.如果⼀些⽅法返回的结果已经是Result类型了, 那就直接返回Result类型的结果即可

完整代码:

复制代码
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wh.advice.model.Result;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof Result) {
            return body;
        }
        if (body instanceof String) {
            return objectMapper.writeValueAsString(Result.success(body));
        }
        return Result.success(body);
    }
}

以上为我个人的小分享,如有问题,欢迎讨论!!!

都看到这了,不如关注一下,给个免费的赞

相关推荐
崎岖Qiu几秒前
【OS笔记44】:磁盘存储管理
笔记·操作系统·os
周周记笔记15 分钟前
ESP32-S3 :开发方式笔记(五)
笔记·单片机·嵌入式硬件
June bug16 分钟前
【实习笔记】Fiddler学习笔记
笔记·学习·fiddler
googleccsdn16 分钟前
ENSP Pro Lab笔记:配置BGP EVPN VXLAN双栈(2)
网络·笔记·网络协议
黎雁·泠崖17 分钟前
Java面向对象:this关键字+构造方法+标准JavaBean
java·开发语言·python
sheji341629 分钟前
【开题答辩全过程】以 基于Java的智慧环卫垃圾收运管理系统设计与实现为例,包含答辩的问题和答案
java·开发语言
JeffDingAI29 分钟前
【Datawhale学习笔记】动手学RNN及LSTM
笔记·rnn·学习
jason成都37 分钟前
实战 | 国产数据库 R2DBC-JDBC 桥接踩坑记 - JetLinks适配达梦数据库
java·数据库·物联网
BullSmall42 分钟前
SEDA (Staged Event-Driven Architecture, 分阶段事件驱动架构
java·spring·架构
Coder_Boy_1 小时前
基于SpringAI的在线考试系统-DDD(领域驱动设计)核心概念及落地架构全总结(含事件驱动协同逻辑)
java·人工智能·spring boot·微服务·架构·事件驱动·领域驱动