springmvc拦截器(Interceptor)

SpringMVC中的拦截器Interceptor用于拦截用户请求,常用于权限验证、日志记录等。其执行顺序为preHandle->Handler->postHandle->afterCompletion。在preHandle中返回true才会执行后续操作,配置时可在xml中定义拦截路径和排除路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是拦截器?

Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。

拦截器的作用:

拦截器可以说相当于是个过滤器:就是把不想要的或不想显示的内容给过滤掉。拦截器可以抽象出一部分代码可以用来完善原来的方法。同时可以减轻代码冗余,提高重用率。

拦截器执行流程:

(1)、程序先执行preHandle()方法,如果该方法的返回值为true,则程序会继续向下执行处理器中的方法,否则将不再向下执行;

(2)、在业务处理器(即控制器Controller类)处理完请求后,会执行postHandle()方法,然后会通过DispatcherServlet向客户端返回响应

(3)、在DispatcherServlet处理完请求后,才会执行afterCompletion()方法

1.拦截器的配置

创建一个类实现handlerInterceptor接口,并重写其中的方法,按照需求进行相应方法的重写,并且preHandle方法的返回值为true时,表示放行后面的方法才会被执行,为false则被拦截

public class Interceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

xml配置
在xml文件中创建拦截器对象放入ioc容器中管理,并指明拦截器的拦截器路径和放行路径

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/home"/>
        <bean id="Interceptor" class="com.letstalk.config.Interceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

2.拦截器的执行顺序

在执行处理器的过程中,springmvc会现根据请求获取一个执行链HandlerExecutionChain类型的都对象,其中包含了handler这个处理器方法和interceptorList是一个拦截器集合,其中包含了springmvc默认自带的拦截器和自己所配置的拦截器并按照在集合中的顺序是,默认的在前面,自己配置的按照配置的先后设置顺序
在这里插入图片描述
(1)preHandle方法的执行顺序
可以看出通过for循环来执行preHandle,执行成功后interceptorIndex加一,也就代表了interceptorIndex执行最后以一个拦截器方法执行成功的拦截器在集合中的索引,
for循环从0开始所以preHandle方法的执行顺序按照配置的前后顺序

 boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HandlerInterceptor[] interceptors = this.getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {
                HandlerInterceptor interceptor = interceptors[i];
                if (!interceptor.preHandle(request, response, this.handler)) {
                    this.triggerAfterCompletion(request, response, (Exception)null);
                    return false;
                }
            }
        }

并在执行PreHandle方法后执行handler方法(处理器方法),并返回个modelandview类型的对象
在这里插入图片描述
(2) postHandle方法的执行顺序
从方法中可以看到for循环中倒序执行postHandle方法,所以postHandle方法的执行顺序是倒序

void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
        HandlerInterceptor[] interceptors = this.getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for(int i = interceptors.length - 1; i >= 0; --i) {
                HandlerInterceptor interceptor = interceptors[i];
                interceptor.postHandle(request, response, this.handler, mv);
            }
        }

    }

从图可知posthandle方法在执行完成处理器方法之后
在这里插入图片描述
(3)afterCompletion方法的执行顺序
可以看出afterCompletion的执行顺序是从interceptorIndex开始倒序,也就是最后执行成功的拦截器开始倒序到第一个拦截器

void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) throws Exception {
        HandlerInterceptor[] interceptors = this.getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for(int i = this.interceptorIndex; i >= 0; --i) {
                HandlerInterceptor interceptor = interceptors[i];

                try {
                    interceptor.afterCompletion(request, response, this.handler, ex);
                } catch (Throwable var8) {
                    logger.error("HandlerInterceptor.afterCompletion threw exception", var8);
                }
            }
        }
    }

afterCompletion方法执行在视图processDispatchResult方法之后,也就是视图被数据渲染之后
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值