为什么会有统⼀数据返回?
其实统一数据返回是运用了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格式的数据
统⼀的数据返回格式的实现
- 添加类注解@ControllerAdvice,实现接口ResponseBodyAdvice
- 重写responseAdvice方法
- 重写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);
}
}
以上为我个人的小分享,如有问题,欢迎讨论!!!
都看到这了,不如关注一下,给个免费的赞