统一数据返回格式 & 统一异常处理
1. 统一数据返回格式
强制登录案例中,我们共做了两部分⼯作
- 通过Session来判断⽤⼾是否登录
- 对后端返回数据进⾏封装,告知前端处理的结果
回顾
后端统⼀返回结果
@Data public class Result<T> { private int status; private String errorMessage; private T data; }
后端逻辑处理
@RequestMapping("/getListByPage") public Result getListByPage(PageRequest pageRequest) { log.info("获取图书列表, pageRequest:{}", pageRequest); //⽤⼾登录, 返回图书列表 PageResult<BookInfo> pageResult = bookService.getBookListByPage(pageRequest); log.info("获取图书列表222, pageRequest:{}", pageResult); return Result.success(pageResult); }
Result.success(pageResult)就是对返回数据进⾏了封装
拦截器帮我们实现了第⼀个功能,接下来看SpringBoot对第⼆个功能如何⽀持
1.1 快速入门
统⼀的数据返回格式使⽤@ControllerAdvice 和ResponseBodyAdvice 的⽅式实现 @ControllerAdvice 表⽰控制器通知类
添加类 ResponseAdvice ,实现 ResponseBodyAdvice 接⼝,并在类上添加 @ControllerAdvice 注解
import com.example.demo.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);
}
}
- supports⽅法:判断是否要执⾏beforeBodyWrite⽅法.true为执⾏,false不执⾏.通过该⽅法可以 选择哪些类或哪些⽅法的response要进⾏处理,其他的不进⾏处理.
从returnType获取类名和⽅法名
//获取执⾏的类 Class<?> declaringClass = returnType.getMethod().getDeclaringClass(); //获取执⾏的⽅法 Method method = returnType.getMethod();
- beforeBodyWrite⽅法:对response⽅法进⾏具体操作处理
测试
测试接⼝:http://127.0.0.1:8080/book/queryBookById?bookId=1
添加统⼀数据返回格式之前:
添加统一数据返回格式之后:
1.2 存在问题
我们继续测试修改图书的接口: http://127.0.0.1:8080/book/updateBook
结果显示, 发生内部错误
查看数据库, 发现数据库操作成功
查看日志, 日志报错:
多测试几种不同的返回结果, 发现只有返回结果为 String类型时才有这种错误发生.
测试代码:
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/test")
@RestController
public class TestController {
@RequestMapping("/t1")
p