一、拦截器核心概念
1.1 拦截器 vs 过滤器
特性 |
过滤器 (Filter) |
拦截器 (Interceptor) |
依赖关系 |
Servlet容器 |
Spring MVC框架 |
作用范围 |
所有Web请求 |
Controller请求 |
实现机制 |
Java EE标准 |
Java反射+AOP |
生命周期 |
服务器启动时初始化 |
随Spring容器初始化 |
功能场景 |
字符编码、安全过滤 |
权限校验、日志记录、性能监控 |
1.2 核心接口 HandlerInterceptor
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
System.out.println("===== 身份验证拦截器启动 =====");
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) {
System.out.println("===== 处理响应数据 =====");
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
System.out.println("===== 清理资源 =====");
}
}
二、拦截器配置指南
2.1 XML配置方式
<mvc:interceptors>
<bean class="cn.cjxy.interceptor.GlobalInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/admin/**"/>
<mvc:exclude-mapping path="/admin/login"/>
<bean class="cn.cjxy.interceptor.AdminAuthInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
2.2 注解配置方式(Spring Boot)
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/static/**");
}
}
2.3 拦截规则
符号 |
说明 |
? |
匹配任何一个字符 |
* |
匹配任何长度的字符 |
** |
匹配多级目录的路径 |
三、执行顺序与调试
3.1 多个拦截器执行流程
请求到达
↓
Interceptor1.preHandle()
↓
Interceptor2.preHandle()
↓
Controller执行
↓
Interceptor2.postHandle()
↓
Interceptor1.postHandle()
↓
视图渲染
↓
Interceptor2.afterCompletion()
↓
Interceptor1.afterCompletion()
3.2 常见问题排查
- 拦截器未生效
- 检查XML命名空间声明:
xmlns:mvc="http://www.springframework.org/schema/mvc"
- 验证路径模式是否正确:
<mvc:mapping path="/api/**"/>
- 静态资源被拦截
<mvc:exclude-mapping path="/resources/**"/>
四、实例
4.1 拦截器
public class InterceptorDemo implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse
response, Object handler) throws Exception {
System.out.println("prehandle........................");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse
response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle--------------------------");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse
response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion++++++++++++++++++-");
}
}
4.2 xml 配置
<mvc:interceptors>
<mvc:interceptor>
controller
<mvc:mapping path="/user/**"/>
<mvc:exclude-mapping path="/user/register"/>
<mvc:exclude-mapping path="/user/login"/>
<bean class="cn.cjxy.interceptor.InterceptorDemo"></bean>
</mvc:interceptor>
</mvc:interceptors>
4.3 Controller 配置
@RequestMapping("/user")
@RestController
public class UserController {
@GetMapping("/login")
public String login() {
System.out.println("login");
return "login";
}
@GetMapping("/register")
public String register() {
System.out.println("register");
return "register";
}
@GetMapping("{id}")
public String findById(@PathVariable Integer id) {
System.out.println("findById");
return "findById: " + id;
}
@GetMapping
public String findAll() {
System.out.println("findAll");
return "findAll";
}
@GetMapping("/hello")
public ModelAndView hello() {
ModelAndView mv = new ModelAndView();
System.out.println("handler...");
mv.setViewName("/hello.jsp");
return mv;
}
}
Hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>我是jsp页面---------</h1>
<%
System.out.println("页面渲染");
%>
</body>
</html>