Spring 拦截器:你的请求休想逃过我的五指山!

京东云开发者
• 阅读 18

拦截器概述

在Spring框架中,拦截器(Interceptor)是一种强大的机制,它允许开发者在请求处理的不同阶段插入自定义逻辑。WebApplicationContext作为Spring Web应用的上下文容器,为拦截器的配置和管理提供了基础支持。

拦截器主要作用于以下场景:
权限验证
日志记录
性能监控
事务管理
通用行为注入等

拦截器与WebApplicationContext的关系

WebApplicationContext是Spring Web应用的IoC容器扩展,它继承自ApplicationContext,并添加了Web应用特有的功能。拦截器通过WebApplicationContext进行注册和管理,成为请求处理管道的一部分。

public interface WebApplicationContext extends ApplicationContext {
    String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";

    ServletContext getServletContext();
}

拦截器类型

HandlerInterceptor

最常用的拦截器接口,定义了三个关键方法:

public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, 
                             HttpServletResponse response, 
                             Object handler) throws Exception {
        return true;
    }

    default void postHandle(HttpServletRequest request, 
                          HttpServletResponse response, 
                          Object handler,
                          ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, 
                               HttpServletResponse response, 
                               Object handler, 
                               Exception ex) throws Exception {
    }
}

AsyncHandlerInterceptor

HandlerInterceptor的扩展,增加了异步处理的支持。

WebRequestInterceptor

与HandlerInterceptor类似,但提供了更通用的WebRequest抽象,不依赖于Servlet API。

拦截器配置

XML配置方式









Java配置方式

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoggingInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/static/**");

        registry.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/admin/**");
    }
}

注解方式

@Component
public class MyInterceptor implements HandlerInterceptor {
    // 实现方法
}

@Configuration
public class InterceptorConfig {

    @Autowired
    private MyInterceptor myInterceptor;

    @Bean
    public WebMvcConfigurer adapter() {
        return new WebMvcConfigurer() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(myInterceptor);
            }
        };
    }
}

拦截器执行流程

拦截器在DispatcherServlet的处理流程中扮演重要角色:

  • preHandle:在处理器执行前调用

返回true继续执行

返回false中断请求处理

  • postHandle:在处理器执行后,视图渲染前调用

可修改ModelAndView

  • afterCompletion:在完整请求完成后调用

适合资源清理

Spring 拦截器:你的请求休想逃过我的五指山!

高级拦截器特性

拦截器顺序控制

可以通过order属性控制多个拦截器的执行顺序:

registry.addInterceptor(new InterceptorA()).order(1);
registry.addInterceptor(new InterceptorB()).order(2);

路径匹配模式

支持Ant风格的路径模式:

  1. ? 匹配一个字符
    • 匹配零个或多个字符
  2. ** 匹配零个或多个目录

异步请求处理

对于异步请求,afterConcurrentHandlingStarted方法会被调用而不是postHandle和afterCompletion。

拦截器与过滤器的区别

特性 拦截器(Interceptor) 过滤器(Filter)
容器依赖 Spring容器 Servlet容器
作用范围 Spring MVC处理的请求 所有进入容器的请求
访问对象 可以访问Handler和方法信息 只能访问ServletRequest/Response
执行时机 在DispatcherServlet内部执行 在DispatcherServlet外部执行
依赖注入 支持 不支持

实际应用示例

日志拦截器

public class LoggingInterceptor implements HandlerInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) {
        long startTime = System.currentTimeMillis();
        request.setAttribute("startTime", startTime);
        logger.info("Request URL: {} : Start Time={}", 
                   request.getRequestURL(), startTime);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, 
                               HttpServletResponse response, 
                               Object handler, 
                               Exception ex) {
        long startTime = (Long) request.getAttribute("startTime");
        long endTime = System.currentTimeMillis();
        logger.info("Request URL: {} : End Time={} : Time Taken={}ms", 
                   request.getRequestURL(), endTime, (endTime - startTime));
    }
}

认证拦截器

public class AuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
                            HttpServletResponse response,
                            Object handler) throws Exception {

        HttpSession session = request.getSession();
        if (session.getAttribute("user") == null) {
            response.sendRedirect("/login");
            return false;
        }
        return true;
    }
}

DEMO实测效果

被拦截
Spring 拦截器:你的请求休想逃过我的五指山!

未被拦截
Spring 拦截器:你的请求休想逃过我的五指山!

点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
springmvc详解
spring和struts2的区别:1.springmvc是方法级别的拦截器,struts是类级别的拦截器,springmvc一个方法对应一个request上下文而struts2一个对象对应一个request上下文。springmvc无限接近于0配置,而struts需要大量的配置2.springmvc支持单例开发,二struts最好使用多例开发
Easter79 Easter79
3年前
springboot2.0+ 使用拦截器导致静态资源被拦截
在spring1.0的版本中,配置拦截器后是不会拦截静态资源的。其配置如下:@ConfigurationpublicclassWebMvcConfigextendsWebMvcConfigurerAdapter{@AutowiredprivateRememberAuthenti
Stella981 Stella981
3年前
Mybatis拦截器
1.介绍:   我自己理解中的mybatis拦截器,和普通拦截器一样,在执行一段程序之前对其做一些特殊处理,网上一般都是用其做分页处理、日志记录...,实现原理就是在预处理前对其进行一些处理2.简单说明:  mybatis提供了一个Interceptor接口,方便扩展所需的操作  Object intercept(Invocation in
Stella981 Stella981
3年前
Spring mvc之拦截器介绍
一、拦截器介绍 (1)拦截器概念介绍        拦截器(Interceptor)是Spring的核心功能之一,它可以在用户请求Action的之前或之后进行一些业务处理。        很多从ASP.NET转过来的开发人员把它叫做过滤器。(2)拦截器方法执行顺序
Wesley13 Wesley13
3年前
ng6中,在HTTP拦截器里,异步请求数据,之后再返回拦截器继续执行用户请求的方法研究
一、问题背景:   上面绕口的标题不知道大家看不看的懂。通常我们用拦截器就是两个目的,1、在请求头里统一添加请求头。2、对响应结果预先处理。   我现在项目就是利用拦截器,在请求头里增加:'Authorization':this.storage.token的请求头。//最精简的一个拦截器。一会儿
Stella981 Stella981
3年前
Mybatis拦截器分析
【基本思路】拦截器在哪里拦截?什么情况下才会拦截代理?怎么代理呢?只要搞清楚这些,基本的拦截器功能也3拦截器实现原理mybatis支持拦截器,实现的原理就是利用JDK的动态代理。拦截器在哪里呢?mybatis到底提供几处可以拦截呢?请看下图,通过分析源码可知基本查询流程如下:!mybatis的interceptor拦截器流程图(http:
Easter79 Easter79
3年前
SpringBoot2.0 基础案例(05):多个拦截器配置和使用场景
本文源码GitHub:知了一笑https://github.com/cicadasmile/springbootbase一、拦截器简介1、拦截器定义拦截器,请求的接口被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。拦截器主要用来按照指定规则拒
Stella981 Stella981
3年前
SpringBoot2.0 基础案例(05):多个拦截器配置和使用场景
本文源码GitHub:知了一笑https://github.com/cicadasmile/springbootbase一、拦截器简介1、拦截器定义拦截器,请求的接口被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。拦截器主要用来按照指定规则拒
Easter79 Easter79
3年前
SSM框架项目的mvc拦截器
为了防止用户在不登录的情况下通过并接请求直接访问系统,我们需要通过session和拦截器来防止这样的情况。拦截器的配置:为拦截器建立一个包:interceptor,并在包里建立LoginInterceptor拦截器类!(https://oscimg.oschina.net/oscnet/0c550371593ccb1aa7a33fa7b7
Stella981 Stella981
3年前
SSM框架项目的mvc拦截器
为了防止用户在不登录的情况下通过并接请求直接访问系统,我们需要通过session和拦截器来防止这样的情况。拦截器的配置:为拦截器建立一个包:interceptor,并在包里建立LoginInterceptor拦截器类!(https://oscimg.oschina.net/oscnet/0c550371593ccb1aa7a33fa7b7