您现在的位置是:首页 >技术杂谈 >Spring Boot :统一功能处理网站首页技术杂谈
Spring Boot :统一功能处理
在用户登陆验证的业务中,如果只是使用Spring AOP的话,session无法获取的,还有各种参数(request等)很难获取,这时候Spring拦截器就发挥了重大的作用了。
1.Spring 拦截器
创建拦截器分俩步:1.创建自定义拦截器 2.将自定义加入到WebMvcConfigurer 的 addInterceptors
方法中
上图是创建自定义拦截器的具体细节。要注意的是preHandle方法返回的是boolean类型,如果返回的是true的话就证明拦截器验证成功,后续的业务代码正常执行,如果是false的话,证明验证不成功,后续的流程的业务代码就不要运行了。
这一步就是将拦截器加入到系统配置中。
以上的操作就实现了简单的拦截器的功能了,拦截所有除了img和login路径的所有url。
2.拦截器实现原理
正常的业务逻辑是用户调用的时候,先到了controller层再到service层再到Mapper层最后调用数据库,而在加上拦截器之后,就会在Controller层之前进行了一个预处理也就是加了个拦截器。
所有的 Controller 执⾏都会通过⼀个调度器 DispatcherServlet 来实现,⽽所有⽅法都会执⾏ DispatcherServlet 中的 doDispatch 调度⽅法,在开始执⾏ Controller 之前,会先调⽤ 预处理⽅法 applyPreHandle,在 applyPreHandle 中会获取所有的拦截器 HandlerInterceptor 并执⾏拦截器中
的 preHandle ⽅法,这样就会咱们前⾯定义的拦截器对应上了。
3.统一异常处理
一样的分俩步进行操作:
3.1创建一个异常处理类
3.2 创建业务方法
要知道的是第二个业务方法是保底操作。
结果:
我们要注意的是这里优先匹配的是空指针,所以总结下来:优先匹配子类,找不到再往上找。
4. 统一数据返回
统⼀数据返回格式的优点有很多,⽐如以下⼏个:
1. ⽅便前端程序员更好的接收和解析后端数据接⼝返回的数据。
2. 降低前端程序员和后端程序员的沟通成本,按照某个格式实现就⾏了,因为所有接⼝都是这样返回的。
3. 有利于项⽬统⼀数据的维护和修改。
4. 有利于后端技术部⻔的统⼀规范的标准制定,不会出现稀奇古怪的返回内容。
统⼀的数据返回格式可以使⽤ @ControllerAdvice + ResponseBodyAdvice 的⽅式实现:
以上的代码无论你是返回一个hashmap类型还是int类型 到最后返回到前端都是规定好的hashmap数据,这就很规范了,但是还有一个问题:
4.1 如果controller返回的String会报错
我们知道我们是想把这个String转成hashmap的,但是为什么会报hashmap无法转成String的错误呢?
先看这统一数据返回的执行流程
分为三步:
1.方法返回的String
2.统一数据返回之前的处理:String -> HashMap
3.将HashMap转成 application/json 的字符串
这时候我们就能看出来问题是出现在第三步了,第三步的具体细节是:它会先判断源body值是String还是其他类型,如果是String会使用StringHttpMessageConverter进行转换,其他的类型则是会使用HttpMessageConverter进行转换,但是现在是用HashMap转成成字符串的,而使用的这个转换器只能将String类型转换字符串,因此会报错。
总结一下就是当前的你拿到的数据不是String但是你用的转换器确实String的,当然会报错了。
4.2 报错的解决方案
4.2.1 去掉StringHttpMessageConverter
加一个配置就ok了。
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.removeIf(converter -> converter instanceof StringHttpMessageConverter);
}
}
4.2.2 在数据统一重写时单独处理String类型,让其返回一个String字符串不是HashMap
这个也有俩种方式,一个是自己拼一个json格式的字符串。还有一个就是jackson工具将源String转成json格式的字符串。