SpringMVC拦截器
SpringMVC拦截器
- 什么是拦截器
- 拦截器和过滤器的区别
- SpringMVC 拦截器的工作原理
- 拦截器的配置
- 拦截器的配置主要有两种方式
- XML 配置方式
- Java配置方式
- 创建一个拦截器
- 拦截器的应用场景
- 拦截器的执行顺序
什么是拦截器
SpringMVC 的拦截器(Interceptor)是指在请求处理的不同阶段执行的自定义逻辑。它的作用类似于 Servlet 的过滤器(Filter),但拦截器比过滤器提供了更多的灵活性和控制,可以在请求的不同生命周期内进行拦截。
用于拦截用户的请求并作出相应的处理,比如通过拦截器来进行用户权限验证或者用来判断用户是否登录。SpringMVC拦截器是可插拔式的设计,需要某一功能拦截器,就需要在配置文件中应用拦截器即可;如果不需要这个功能拦截器,只需要在配置文件中取消该拦截器即可。
拦截器和过滤器的区别
- 过滤器依赖于servlet,而拦截器技术属于SpringMVC
- 过滤器可对所有请求起作用,拦截器只对访问controller层的请求起作用。
- 过滤器会比拦截器先执行。拦截器(Interceptor)是在Servlet和Controller控制器之间执行;而过滤器(Filter)是在请求进入Tomcat容器之后 但是在请求进入Servlet之前执行。
SpringMVC 拦截器的工作原理
SpringMVC 拦截器是通过实现 HandlerInterceptor 接口来定义的,通常有三个方法:
-
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler):在请求处理前执行。可以用来进行身份验证、权限检查等操作。如果返回 false,请求会被拦截,不会继续向下执行(即请求不会传递给 Controller 和后续的视图解析过程);如果返回 true,请求会继续传递到 Controller 中。
-
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView):在请求处理后,视图渲染前执行。可以用来修改 ModelAndView,即在 Controller 执行后,但还未渲染视图时进行操作。
-
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex):在请求处理完毕后执行,通常用于资源清理工作。即使请求处理过程中出现了异常,afterCompletion 也会被调用。可以在这里做日志记录等操作。
拦截器的配置
拦截器的配置主要有两种方式
基于 XML 配置和基于 Java 配置
XML 配置方式
在 spring-mvc.xml 中配置拦截器。例如,定义一个拦截器并将其应用到特定的 URL 路径上。
<mvc:interceptors>
<bean class="com.example.interceptor.MyInterceptor">
<!-- 这里可以配置拦截器的属性 -->
</bean>
</mvc:interceptors>
Java配置方式
在 Spring 配置类中配置拦截器。需要实现 WebMvcConfigurer 接口,并重写 addInterceptors 方法。
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/**") // 拦截所有请求
.excludePathPatterns("/login", "/register"); // 排除特定的请求
}
}
创建一个拦截器
拦截器需要实现 HandlerInterceptor 接口,重写其中的三个方法:preHandle、postHandle 和 afterCompletion。
public class MyInterceptor implements HandlerInterceptor {
// 在请求处理前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle: 请求即将开始处理");
// 可以进行权限校验、日志记录等操作
// 如果返回 false,表示拦截该请求,不会继续向下执行
return true; // 返回 true 继续执行,返回 false 拦截请求
}
// 在请求处理后,视图渲染前执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle: 请求处理后,但视图渲染前");
// 可以修改 ModelAndView,添加额外的模型数据
}
// 在整个请求完成后执行(即视图渲染完成后)
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion: 请求处理完毕,视图渲染完成");
// 可以用来做日志记录、清理资源等操作
}
}
拦截器的应用场景
拦截器的执行顺序
拦截器的执行顺序是按其在 InterceptorRegistry 中配置的顺序执行的。preHandle 在请求到达 Controller 之前执行,postHandle 在 Controller 执行后但视图渲染前执行,afterCompletion 在视图渲染完成后执行。
!!! 多个拦截器的执行流程:当多个拦截器同时工作时,它们的preHandle()方法会按照配置文件中拦截器的配置顺序执行,而它们的postHandle()方法和afterCompletion()方法则会按照配置顺序的反序执行。