- SpringMVC的拦截器
- SpringMVC拦截器简介
- SpringMVC的执行原理
- 拦截器的实现方式
三、SpringMVC的拦截器
3.1 SpringMVC拦截器简介
SpringMVC 中的
Interceptor
拦截器,它的主要作用是拦截指定的用户请求,并进行相应的预处理与后处理。其拦截的时间点在 “处理器映射器根据用户提交的请求映射出了所要执行的处理器类,并且也找到了要执行该处理器类的处理器适配器,在处理器适配器执行处理器之前”。当然,在处理器映射器映射出所要执行的处理器类时,已经将拦截器与处理器组合为了一个处理器执行链,并返回给了中央调度器。
- SpringMVC 的拦截器针对请求和响应进行的额外的处理,在请求和响应的过程中添加预处理,后处理和最终处理。
拦截器的应用场景:
- 日志记录:记录请求信息的日志。
- 权限检查,如登录检查。
- 性能检测:检测方法的执行时间。
3.2 SpringMVC的执行原理

拦截器执行的时机:
preHandle()
:在请求被处理之前进行操作,预处理。
- 该方法在处理器方法执行之前执行。
- 其返回值为
boolean
,若为true
,则紧接着会执行处理器方法,且会将afterCompletion()
方法放入到一个专门的方法栈中等待执行。
postHandle()
:在请求被处理之后,但结果还没有渲染前进行操作,可以改变响应结果,后处理。
- 该方法在处理器方法执行之后执行。
- 处理器方法若最终未被执行,则该方法不会执行。
- 由于该方法是在处理器方法执行完后执行,且该方法参数中包含
ModelAndView
,所以该方法可以修改处理器方法的处理结果数据,且可以修改跳转方向。
afterCompletion()
:所有的请求响应结束后执行善后工作,清理对象,关闭资源 ,最终处理。
- 当
preHandle()
方法返回true
时,会将该方法放到专门的方法栈中,等到对请求进行响应的所有工作完成之后才执行该方法。即该方法是在中央调度器渲染(数据填充)了响应页面之后执行的,此时对ModelAndView
再操作也对响应无济于事。
- 当
3.3 拦截器的实现方式
3.3.1 继承HandlerInterceptorAdapter父类
3.3.2 实现HandlerInterceptor接口
推荐使用实现接口的方式。因为在 Java 中类的继承是单一继承,父类的继承应该留给核心业务,而不是交叉业务。
接下来通过实现
HandlerInterceptor
接口的方式来实现一个权限验证拦截器:新建一个
SpringMVC-006-interceptor
模块,模块的搭建过程类似于1.5 ★基于注解的SpringMVC程序
中的流程。pom.xml
、springmvc.xml
配置文件的内容可以直接看SpringMVC-learning-code
代码。webapp
目录下的文件内容也直接看SpringMVC-learning-code
代码。在用户登录功能验证的基础上,添加拦截器功能。
开发拦截器,实现
HandlerInterceptor
接口,并重写preHandle()
方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package com.f.springmvc.interceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
/**
* @author fzy
* @date 2024/2/20 14:44
*/
public class LoginInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 判断是否登录过
if (request.getSession().getAttribute("user") == null) {
request.setAttribute("msg", "您还未登录, 请先登录...");
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
// 放行请求
return true;
}
}然后在
springmvc.xml
配置文件中注册该拦截器:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.f.springmvc.controller"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--启用注解驱动-->
<mvc:annotation-driven/>
<!--注册拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--要拦截的请求-->
<mvc:mapping path="/*"/>
<!--设置放行的请求-->
<mvc:exclude-mapping path="/login"/>
<!--配置具体的拦截器-->
<bean class="com.f.springmvc.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>然后该拦截器就能根据配置对指定的请求进行拦截了。类似于
JavaWeb
笔记中的过滤器的作用。