1. 拦截器
1.1 拦截器快速⼊⻔
什么是拦截器?
拦截器是Spring框架提供的核⼼功能之⼀, 主要⽤来拦截⽤⼾的请求, 在指定⽅法前后, 根据业务需要执⾏预先设定的代码.
也就是说, 允许开发⼈员提前预定义⼀些逻辑, 在⽤⼾的请求响应前后执⾏. 也可以在⽤⼾请求前阻⽌其执⾏.
在拦截器当中,开发⼈员可以在应⽤程序中做⼀些通⽤性的操作, ⽐如通过拦截器来拦截前端发来的请求, 判断Session中是否有登录⽤⼾的信息. 如果有就可以放⾏, 如果没有就进⾏拦截.
⽐如我们去银⾏办理业务, 在办理业务前后, 就可以加⼀些拦截操作
办理业务之前, 先取号, 如果带⾝份证了就取号成功
业务办理结束, 给业务办理⼈员的服务进⾏评价.
这些就是"拦截器"做的⼯作.
![](https://i-blog.csdnimg.cn/direct/3e545d6628d849a493f135ab9dca2dee.png)
拦截器的使⽤步骤分为两步:
1.
定义拦截器
⾃定义拦截器:实现HandlerInterceptor接⼝,并重写其所有⽅法
![](https://i-blog.csdnimg.cn/direct/3ca9f4315159469e9ff01ec0addbefd9.png)
•
preHandle()⽅法:⽬标⽅法执⾏前执⾏. 返回true: 继续执⾏后续操作; 返回false: 中断后续操作.
•
postHandle()⽅法:⽬标⽅法执⾏后执⾏
•
afterCompletion()⽅法:视图渲染完毕后执⾏,最后执⾏(后端开发现在⼏乎不涉及视图, 暂不了
解)
2.
注册配置拦截器
注册配置拦截器:实现WebMvcConfigurer接⼝,并重写addInterceptors⽅法
![](https://i-blog.csdnimg.cn/direct/61271e480eea48c3892e41d76ddf6fa4.png)
启动服务, 试试访问任意请求, 观察后端⽇志
![](https://i-blog.csdnimg.cn/direct/dcb627907a2745c2a61c260378214283.png)
可以看到preHandle ⽅法执⾏之后就放⾏了, 开始执⾏⽬标⽅法, ⽬标⽅法执⾏完成之后执⾏
postHandle和afterCompletion⽅法
我们把拦截器中preHandle⽅法的返回值改为false, 再观察运⾏结果
![](https://i-blog.csdnimg.cn/direct/a922bea2ace841b19ad8475f6f1ae656.png)
可以看到, 拦截器拦截了请求, 没有进⾏响应.
1.2 拦截器详解
拦截器的⼊⻔程序完成之后,接下来我们来介绍拦截器的使⽤细节。拦截器的使⽤细节我们主要介绍
两个部分:
1.
拦截器的拦截路径配置
2.
拦截器实现原理
1.2.1 拦截路径
拦截路径是指我们定义的这个拦截器, 对哪些请求⽣效.
我们在注册配置拦截器的时候, 通过
addPathPatterns()
⽅法指定要拦截哪些请求. 也可以通过
excludePathPatterns()
指定不拦截哪些请求
上述代码中, 我们配置的是
/**
, 表⽰拦截所有的请求
⽐如⽤⼾登录校验, 我们希望可以对除了登录之外所有的路径⽣效
![](https://i-blog.csdnimg.cn/direct/2afb07abdbb1481180ebad41a42af17d.png)
![](https://i-blog.csdnimg.cn/direct/60c5bcfdb4cd4df8af1e26e3bfd5eedb.png)
以上拦截规则可以拦截此项⽬中的使⽤ URL,包括静态⽂件(图⽚⽂件, JS 和 CSS 等⽂件).
![](https://i-blog.csdnimg.cn/direct/b5d7d56b37f64a10b9dc27fbdd1d2861.png)
有了拦截器之后,会在调⽤ Controller 之前进⾏相应的业务处理,执⾏的流程如下图
![](https://i-blog.csdnimg.cn/direct/b4eab5be8941432485ba429a095ddf3e.png)
1.
添加拦截器后, 执⾏Controller的⽅法之前, 请求会先被拦截器拦截住. 执⾏
preHandle()
⽅法,
这个⽅法需要返回⼀个布尔类型的值. 如果返回true, 就表⽰放⾏本次操作, 继续访问controller中的
⽅法. 如果返回false,则不会放⾏(controller中的⽅法也不会执⾏).
2.
controller当中的⽅法执⾏完毕后,再回过来执⾏
postHandle()
这个⽅法以及
afterCompletion()
⽅法,执⾏完毕之后,最终给浏览器响应数据
适配器模式
HandlerAdapter 在 Spring MVC 中使⽤了适配器模式
适配器模式定义
适配器模式, 也叫包装器模式. 将⼀个类的接⼝,转换成客⼾期望的另⼀个接⼝, 适配器让原本接⼝不兼容的类可以合作⽆间.
简单来说就是⽬标类不能直接使⽤, 通过⼀个新类进⾏包装⼀下, 适配调⽤⽅使⽤. 把两个不兼容的接⼝通过⼀定的⽅式使之兼容
![](https://i-blog.csdnimg.cn/direct/0ccb077362224bbc82e623d6fefe4ac4.png)
适配器模式⻆⾊
•
Target: ⽬标接⼝ (可以是抽象类或接⼝), 客⼾希望直接⽤的接⼝
•
Adaptee: 适配者, 但是与Target不兼容
•
Adapter: 适配器类, 此模式的核⼼. 通过继承或者引⽤适配者的对象, 把适配者转为⽬标接⼝
•
client: 需要使⽤适配器的对象
适配器模式的实现
场景: 前⾯学习的slf4j 就使⽤了适配器模式, slf4j提供了⼀系列打印⽇志的api, 底层调⽤的是log4j 或者logback来打⽇志, 我们作为调⽤者, 只需要调⽤slf4j的api就⾏了.
![](https://i-blog.csdnimg.cn/direct/eab92b3bce114de4b2b15c2de626e92e.png)
slf4j相当于接口A,log4j相当于是接口B,由于AB不适配,所以需要一个适配器来进行转换,Slf4jLog4jAdapter这个接口就是用来进行转换的,这个类实现slf4j这个接口,然后重写一下该接口的log方法,然后在这个适配器类里定义一个变量是log4j这个对象,通过构造方法给该对象进行实例化,在重写的log方法中,调用log4j中的打印方法,在main方法中,通过实现slf4jApi这个接口,调用这个对象即可完成适配器模式
适配器模式应⽤场景
⼀般来说,适配器模式可以看作⼀种"补偿模式",⽤来补救设计上的缺陷. 应⽤这种模式算是"⽆奈之举", 如果在设计初期,我们就能协调规避接⼝不兼容的问题, 就不需要使⽤适配器模式了
所以适配器模式更多的应⽤场景主要是对正在运⾏的代码进⾏改造, 并且希望可以复⽤原有代码实现新的功能. ⽐如版本升级等
统⼀数据返回格式
快速入门
统⼀的数据返回格式使⽤ @ControllerAdvice 和 ResponseBodyAdvice 的⽅式实现 @ControllerAdvice 表⽰控制器通知类 添加类 ResponseAdvice , 实现 ResponseBodyAdvice 接⼝, 并在类上添加 @ControllerAdvice 注解
•
supports⽅法: 判断是否要执⾏beforeBodyWrite⽅法. true为执⾏, false不执⾏. 通过该⽅法可以
选择哪些类或哪些⽅法的response要进⾏处理, 其他的不进⾏处理.
存在问题
![](https://i-blog.csdnimg.cn/direct/97a18cbeace740c5917f1341f62673e3.png)
![](https://i-blog.csdnimg.cn/direct/b80174ca55a446398698544eb25b2c34.png)
//
如果返回结果为
String
类型
,
使⽤
SpringBoot
内置提供的
Jackson
来实现信息的序列化
![](https://i-blog.csdnimg.cn/direct/3c8e7121612041328e7517ea0bf5a7b9.png)
如果⼀些⽅法返回的结果已经是Result类型了, 那就直接返回Result类型的结果即可
优点
1.
⽅便前端程序员更好的接收和解析后端数据接⼝返回的数据
2.
降低前端程序员和后端程序员的沟通成本, 按照某个格式实现就可以了, 因为所有接⼝都是这样返回的.
3.
有利于项⽬统⼀数据的维护和修改.
4.
有利于后端技术部⻔的统⼀规范的标准制定, 不会出现稀奇古怪的返回内容.
统⼀异常处理
统⼀异常处理使⽤的是
@ControllerAdvice
+
@ExceptionHandler
来实现的,
@ControllerAdvice
表⽰控制器通知类,
@ExceptionHandler
是异常处理器,两个结合表
⽰当出现异常的时候执⾏某个通知,也就是执⾏某个⽅法事件
![](https://i-blog.csdnimg.cn/direct/6855277ae9f8470dabeb0c7dd73d5ada.png)
类名, ⽅法名和返回值可以⾃定义, 重要的是注解
接⼝返回为数据时, 需要加 @ResponseBody
注解