SpringMVC 拦截器

一、拦截器简介

        拦截器 Interceptor,顾名思义,是对我们当前的请求进行拦截的一种技术。说到拦截器,这里就不得不提一下过滤器 filter 的概念,这两种技术都可以拦截请求,那么她们到底有什么区别呢?

        浏览器发送过来的所有请求首先被过滤器 filter 进行拦截,当请求未被过滤器拦截时,此时请求才会被前端控制器 DispatcherServlet 接收,并根据请求映射,找到具体的控制器(Controller)方法来处理请求。

        而拦截器就是作用在控制器执行的前后,在拦截器中一般有三个抽象方法,分别在 “控制器方法执行前执行”、“控制器方法执行后执行” 和 “渲染视图之后执行”。下面会分别详细的介绍。

二、拦截器配置

2.1 拦截所有请求方式一

        首先创建一个自定义的拦截器类 FirstInterceptor 并实现 HandlerInterceptor 接口,并重写其三个方法,代码如下:

public class FirstInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("FirstInterceptor --> preHandle ");
        // 返回 false 表示拦截,返回 true 表示放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("FirstInterceptor --> postHandle ");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("FirstInterceptor --> afterCompletion ");
    }
}

        在 springMVC 的配置文件中配置拦截器,如下:

    <mvc:interceptors>
        <bean class="com.interceptor.FirstInterceptor"></bean>
    </mvc:interceptors>

2.2 拦截所有请求方式二

        给 FirstInterceptor 类添加注解,交由 IOC 容器进行管理,如下:

@Component
public class FirstInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("FirstInterceptor --> preHandle ");
        // 返回 false 表示拦截,返回 true 表示放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("FirstInterceptor --> postHandle ");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("FirstInterceptor --> afterCompletion ");
    }
}

        在 springMVC 的配置文件中配置拦截器,如下: 

    <mvc:interceptors>
        <ref bean="firstInterceptor"></ref>
    </mvc:interceptors>

        这两种拦截器的配置,将拦截所有的控制器方法,即只要是调用了控制器的方法,都会打印这三个方法的返回值,如下所示:

2.3 拦截指定路径请求方式

        给 FirstInterceptor 类添加注解,交由 IOC 容器进行管理,如下:

@Component
public class FirstInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("FirstInterceptor --> preHandle ");
        // 返回 false 表示拦截,返回 true 表示放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("FirstInterceptor --> postHandle ");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("FirstInterceptor --> afterCompletion ");
    }
}

        在 springMVC 的配置文件中配置拦截器,如下: 

    <mvc:interceptors>
        <mvc:interceptor>
            <!-- 设置需要拦截的路径,/* 表示只匹配上下文路径的一层目录,如果想要拦截所有的话就使用 /** -->
            <mvc:mapping path="/**"/>
            <!-- 排除指定的拦截路径,当访问 / 时不会被拦截器拦截-->
            <mvc:exclude-mapping path="/"/>
            <!-- 指定拦截器-->
            <ref bean="firstInterceptor"></ref>
        </mvc:interceptor>
    </mvc:interceptors>

        当访问 / 路径时不会被拦截,当访问其他的任何路径时,都会被拦截,如下图:

三、拦截器的三个抽象方法

3.1 preHandle

        控制器(controller)方法执行之前执行 preHandle(),其 boolean 类型的返回值表示是否拦截或放行,返回 true 为放行,即调用控制器方法;返回 false 表示拦截,即不调用控制器方法。

3.2 postHandle

        控制器方法执行之后执行 postHandle()

3.3 afterComplation

        处理完视图和模型数据,渲染视图完毕之后执行 afterComplation()

四、多个拦截器执行顺序

4.1 配置多个拦截器

        我们此时再创建一个拦截器 SecondInterceptor,代码如下所示:

@Component
public class SecondInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("SecondInterceptor --> preHandle ");
        // 返回 false 表示拦截,返回 true 表示放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("SecondInterceptor --> postHandle ");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("SecondInterceptor --> afterCompletion ");
    }
}

        在 springMVC 的配置文件中配置这两个拦截器,如下:

    <mvc:interceptors>
        <ref bean="firstInterceptor"></ref>
        <ref bean="secondInterceptor"></ref>
    </mvc:interceptors>

        那这两个拦截器的执行顺序该是什么样子的呢?如下图:

4.2 多个拦截器执行顺序

        若每个拦截器的 preHandle() 都返回 true,此时多个拦截器的执行顺序和拦截器在 SpringMVC 的配置文件的配置顺序有关,preHandle() 会按照配置文件中的顺序执行,而 postHandle()  afterComplation() 会按照配置的反序执行。

        若其中的一个拦截器的 preHandle() 返回 false,那么这个拦截器和它之前拦截器的 preHandle() 都会执行,postHandle() 都不执行,返回 false 的拦截器之前的拦截器的 afterComplation() 会执行。

4.3 案例展示

4.3.1 第一个拦截器返回 false

        当 FirstInterceptor 的 preHandle() 返回 false,而 SecondInterceptor 的 preHandle() 返回 true 时,如下图:

@Component
public class FirstInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("FirstInterceptor --> preHandle ");
        // 返回 false 表示拦截,返回 true 表示放行
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("FirstInterceptor --> postHandle ");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("FirstInterceptor --> afterCompletion ");
    }
}
@Component
public class SecondInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("SecondInterceptor --> preHandle ");
        // 返回 false 表示拦截,返回 true 表示放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("SecondInterceptor --> postHandle ");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("SecondInterceptor --> afterCompletion ");
    }
}

        在 springMVC 的配置文件中配置这两个拦截器,如下:

    <mvc:interceptors>
        <ref bean="firstInterceptor"></ref>
        <ref bean="secondInterceptor"></ref>
    </mvc:interceptors>

        可以看到,只执行了 FirstInterceptor 的 preHandle() 方法,第二个拦截器的任何方法都没执行。

 4.3.1 第二个拦截器返回 false

        当 FirstInterceptor 的 preHandle() 返回 true,而 SecondInterceptor 的 preHandle() 返回 false 时,如下图:

@Component
public class FirstInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("FirstInterceptor --> preHandle ");
        // 返回 false 表示拦截,返回 true 表示放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("FirstInterceptor --> postHandle ");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("FirstInterceptor --> afterCompletion ");
    }
}
@Component
public class SecondInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("SecondInterceptor --> preHandle ");
        // 返回 false 表示拦截,返回 true 表示放行
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("SecondInterceptor --> postHandle ");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("SecondInterceptor --> afterCompletion ");
    }
}

        在 springMVC 的配置文件中配置这两个拦截器,如下:

    <mvc:interceptors>
        <ref bean="firstInterceptor"></ref>
        <ref bean="secondInterceptor"></ref>
    </mvc:interceptors>

        可以看到,执行了 FirstInterceptor SecondInterceptor 的 preHandle() 方法,还执行了 FirstInterceptor afterComplation() ,其他的任何方法都没执行。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐的小三菊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值