前言:为什么要有统一功能处理?
我们在进行数据的返回的时候,不同的方法返回的数据类型也不一样,但是我们前端有时候期望拿到是一样的数据类型。就好比买菜的时候期望最后是用一个大的塑料袋进行包装的。
那么我们可以在HTTP进行响应的之前,做一些事情,让我们返回的数据统一。
目录
目录
一.统一结果返回
1)在项目中添加 ResponseAdvice 类 , 实现了 ResponseBodyAdvice 接口
重写其中的两个方法:
2)两个方法的解释
其中support 方法就像一个开关,返回 false 意味着不对结果进行统一处理,返回 true 意味着需要对结果进行统一处理。
我们要做的事情是在 beforeBodyWrite 中。我们需要返回一个类型,这个类型期望是我们自己写好的 Result 类中封装的数据。
3)异常的情况
我们对五个方法来进行测试
在 t4 测试出现如下情况
很明显这嵌套了两层 data , 可知原本的数据就是已经封装好的了。
t3 的数据错误如下:
数据类型转换错误:Result cannot be cast to java.lang.String
4)解决办法:
t4 解决: 使用类型判断
t3 解决办法:最根本的原因在于底层源码部分出错
二.拦截器
拦截器就好比与是一个保安门卫,在前端发来请求进行访问的时候,只有符合条件的才可以进入。例如登陆场景,只有登陆过的人才可以访问后续内容,如果没有登陆过,那么会强制跳转到登录界面。
1)在项目中加入拦截器
加入拦截器的类 需要实现 HandlerInterceptor 接口,并重写它的方法
2)注册新建拦截器
上面是实现,下面才是实际注册拦截器
注册拦截器的类 需要实现其中的 WebMvcConfigurer 接口,重写其中的方法
代码解读:1. 首先通过 @Autowired 获取到拦截器对象
2. 实现其中的 addInterceptors 方法 ,其中
这样的话,在登陆页面和其他指定页面时,拦截器都会生效。访问的时候,会先进行拦截器校验(具体逻辑在实现 HandlerInterceptor 接口的类中),如果 session 不存在,意味着未登录,就不会返回任何数据。
三.统一异常处理
统⼀异常处理使⽤的是 @ControllerAdvice + @ExceptionHandler 来实现的,
@ControllerAdvice 表⽰控制器通知类, @ExceptionHandler 是异常处理器,两个结合表
⽰当出现异常的时候执⾏某个通知,也就是执⾏某个⽅法事件
我们来写一些测试类,并使用Postman 进行测试
package com.example.springbook.controller; import com.example.springbook.model.BookInfo; import com.example.springbook.model.Result; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/test") @RestController public class TestController { @RequestMapping("/t1") public Boolean t1(){ int a = 10 / 0; //算术异常 return true; } @RequestMapping("/t2") public Integer t2(){ int[] array = {1,2}; System.out.println(array[3]); //数组越界异常 return 1233; } @RequestMapping("/t3") public String t3(){ String bookInfo = null; System.out.println(bookInfo.length()); //空指针异常 return "hello"; } }
测试 :
t1 结果返回了 算数异常 ,并且字符串是我们在异常类中自定义的
t2 返回内部错误 ,但是其实他是数组越界异常,那么为什么没有报错呢?其实我们在实现异常类中,并没有写数组越界异常处理的情况,所以它会直接到 Exception 中,返回内部错误
t3 返回了空指针异常,是我们预期的结果
总结:目前学习了统一结果返回,拦截器,统一异常处理 三个功能。这些功能在实际开发中经常使用。