Spring MVC 拦截器

Spring MVC 拦截器(Interceptor)是 Spring 框架提供的一种用于在请求处理之前和之后对 HTTP 请求进行处理的机制。拦截器常用于处理日志、权限验证、性能监控等功能。

1. 定义拦截器

拦截器需要实现 HandlerInterceptor 接口,主要有三个方法:

  • preHandle(HttpServletRequest request, HttpServletResponse response, Object handler):在请求处理之前执行,返回 true 表示继续执行下一个拦截器或者目标方法,返回 false 则会停止后续拦截器链的执行。
  • postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView):请求处理之后执行,但在视图渲染之前调用。
  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex):请求处理完毕后执行,主要用于清理资源。

2. 创建拦截器

import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {

    // 请求处理之前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle: 请求处理前");
        // 返回true表示继续处理请求,返回false表示请求被拦截,后续处理不会执行
        return true;
    }

    // 请求处理之后执行,但视图渲染之前
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle: 请求处理后,视图渲染前");
    }

    // 请求完全处理之后执行,主要用于资源清理
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion: 请求处理后,视图渲染后");
    }
}

3. 注册拦截器

在 Spring MVC 配置中,你需要将拦截器注册到 HandlerInterceptor 接口中。通常有两种方式来进行配置:

3.1 使用 Java 配置(基于 WebMvcConfigurer

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**")    // 配置拦截路径,所有路径都会被拦截
                .excludePathPatterns("/login", "/signup"); // 排除不需要拦截的路径
    }
}

3.2 使用 XML 配置

如果你使用的是基于 XML 配置的 Spring MVC,你可以在 servlet-context.xml 文件中注册拦截器:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**" />
        <bean class="com.example.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

4.多个拦截器指定顺序

4.1 通过 InterceptorRegistry 顺序控制

WebMvcConfigurer 中,拦截器的执行顺序是按照它们注册的顺序来的。注册的顺序决定了拦截器的执行顺序。第一个注册的拦截器会先执行,依此类推。

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 第一个拦截器
        registry.addInterceptor(new FirstInterceptor())
                .addPathPatterns("/**");

        // 第二个拦截器
        registry.addInterceptor(new SecondInterceptor())
                .addPathPatterns("/**");
    }
}

在这个例子中,FirstInterceptor 会先执行,然后是 SecondInterceptor

4.2 使用 @Order 注解显式指定顺序,配合 Spring Bean 自动装配

你也可以通过 @Order 注解显式指定每个拦截器的执行顺序。@Order 的值越小,拦截器的执行顺序越靠前。

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(1)  // 顺序靠前
public class FirstInterceptor implements HandlerInterceptor {
    // 实现方法
}

@Component
@Order(2)  // 顺序靠后
public class SecondInterceptor implements HandlerInterceptor {
    // 实现方法
}

@Component
@Order(3)  // 最后执行
public class ThirdInterceptor implements HandlerInterceptor {
    // 实现方法
}

在这个例子中,FirstInterceptor 会先执行,然后是 SecondInterceptor,因为 FirstInterceptor@Order 注解值为 1,而 SecondInterceptor 的值为 2

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private FirstInterceptor firstInterceptor;

    @Autowired
    private SecondInterceptor secondInterceptor;

    @Autowired
    private ThirdInterceptor thirdInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(firstInterceptor).addPathPatterns("/**");
        registry.addInterceptor(secondInterceptor).addPathPatterns("/**");
        registry.addInterceptor(thirdInterceptor).addPathPatterns("/**");
    }
}

5.执行顺序

当有多个拦截器时,并且各个方法都未发生异常,执行顺序为

  1. 先顺序执行各个拦截器的 preHandle 方法
  2. 然后执行 目标方法
  3. 然后倒序执行所有拦截器的 postHandle 方法
  4. 最后再倒序执行所有拦截器的 afterCompletion 方法

当 preHandle 发生异常时,postHandle 不会执行,但是 afterCompletion 会执行

posted @   CyrusHuang  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示