Spring MVC 拦截器教程

发布于:2025-05-01 ⋅ 阅读:(46) ⋅ 点赞:(0)

一、拦截器核心概念

1.1 拦截器 vs 过滤器

特性 过滤器 (Filter) 拦截器 (Interceptor)
依赖关系 Servlet容器 Spring MVC框架
作用范围 所有Web请求 Controller请求
实现机制 Java EE标准 Java反射+AOP
生命周期 服务器启动时初始化 随Spring容器初始化
功能场景 字符编码、安全过滤 权限校验、日志记录、性能监控

1.2 核心接口 HandlerInterceptor

public class AuthInterceptor implements HandlerInterceptor {
    
    // 请求到达Controller前执行
    //进入handler之前的处理(选择是否将该请求拦截) 返回true 放行;返回false 拦截
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response,
                           Object handler) {
        System.out.println("===== 身份验证拦截器启动 =====");
        return true; // 返回true放行请求
    }

    // Controller执行后,视图渲染前执行
    @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配置方式

<!-- springmvc.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 常见问题排查

  1. 拦截器未生效
    • 检查XML命名空间声明:xmlns:mvc="http://www.springframework.org/schema/mvc"
    • 验证路径模式是否正确:<mvc:mapping path="/api/**"/>
  2. 静态资源被拦截
<mvc:exclude-mapping path="/resources/**"/>

四、实例

4.1 拦截器

/**
* 拦截请求
* 定义一个拦截器需要实现HandlerInterceptor
*/
public class InterceptorDemo implements HandlerInterceptor {
/**
* 请求执行前执行(handle执行前执行)
* @param request
* @param response
* @param handler 要执行的handler(目标方法)
* @return
* @throws Exception
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse
response, Object handler) throws Exception {
System.out.println("prehandle........................");
return true;
}
/**
* handle执行完之后执行
* @param request
* @param response
* @param handler 要执行的目标方法
* @param modelAndView handler方法所返回的视图和模型,如果未返回则为null
* @throws Exception
*/
public void postHandle(HttpServletRequest request, HttpServletResponse
response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle--------------------------");
}
/**
* 页面渲染之后才会执行
* @param request
* @param response
* @param handler 要执行的目标方法
* @param ex 解析JSP页面出现异常时的对象
* @throws Exception
*/
public void afterCompletion(HttpServletRequest request, HttpServletResponse
response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion++++++++++++++++++-");
}
}

4.2 xml 配置

<!-- 拦截器配置:将定义的拦截器加入的mvc中-->
<mvc:interceptors>
  <!-- 配置单个拦截器-->
  <mvc:interceptor>
    controller
    <!-- path:匹配规则
    : ? 匹配任何一个字符
    * 匹配任何长度的字符
    ** 匹配多级目录的路径
    -->
    <!-- 拦截/user下的所有请求-->
    <mvc:mapping path="/user/**"/>
    <!-- 放行/user/register请求-->
    <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") // /user/login
    public String login() { // 不进入拦截器
        System.out.println("login");
        return "login";
    }

    @GetMapping("/register") // /user/login
    public String register() { // 不进入拦截器
        System.out.println("register");
        return "register";
    }

    @GetMapping("{id}") // /user/3 // 进入拦截器
    public String findById(@PathVariable Integer id) {
        System.out.println("findById");
        return "findById: " + id;
    }

    @GetMapping// /user
    public String findAll() { // 进入拦截器
        System.out.println("findAll");
        return "findAll";
    }

    @GetMapping("/hello") // /user/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>

网站公告

今日签到

点亮在社区的每一天
去签到