springmvc学习笔记(28)——自定义拦截器

springmvc 专栏收录该内容
34 篇文章 2 订阅

1. 自定义拦截器

在之前的一篇笔记中有使用到拦截器,当时没有对拦截器做解释,在这里:springmvc学习笔记(13)——国际化资源文件

所谓的拦截器,就是用来拦截请求,因此我们可以对用户发来的请求做处理。

  • 写一个类,实现拦截器的接口
package com.zj.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class FirstInterceptor implements HandlerInterceptor{

    /**
     * 该方法在 目标方法之前被调用
     * 可以用来做 权限,日志,事务
     * 若 return false,后续的拦截器和目标方法将不被调用
     * 若 return true,后续的拦截器和目标方法正常调用
     */
    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    /**
     * 该方法在 目标方法之后,渲染视图之前 被调用
     * 可以用来 修改请求域,修改目标视图等
     */
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throws Exception {
        System.out.println("postHandle");

    }
    /**
     * 该方法在 目标方法被调用,渲染视图之后被调用
     * 可以用来 释放资源
     */
    @Override
    public void afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        System.out.println("afterCompletion");

    }


}

代码中已经有了详细的注释,包括三个方法的调用顺序方法
在三个方法中打印出一句话,以便我们能看到效果

  • 让拦截器起作用,就要在springmvc配置文件中配置
        <!-- 拦截器 -->
    <mvc:interceptors>
        <!-- 配置自定义的拦截器 -->
        <bean class="com.zj.interceptor.FirstInterceptor"></bean>
    </mvc:interceptors>

到这里,配置就完成了,访问任意目标方法,控制台打印出如下结果
这里写图片描述

2. 配置拦截器的作用范围

    <mvc:interceptors>

        <!-- 配置自定义的拦截器 -->
        <bean class="com.zj.interceptor.FirstInterceptor"></bean>

        <mvc:interceptor>
            <!-- 只有访问/hello这个路径,拦截器才起作用 -->
            <mvc:mapping path="/hello"/>
            <!-- 
                除了/index这个路径,其他都起作用
                <mvc:exclude-mapping path="/index"/>
             -->
            <bean class="com.zj.interceptor.SecondInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
  • 在最外层是一个mvc:interceptors,在里面,我们又配置了一个mvc:interceptor。请注意,前者有s,后者没有。
  • 在mvc:interceptor中,我们可以配置拦截器SecondInterceptor的作用范围,只作用于某个路径或者只有某个路径不被作用

3. 多个拦截器的调用顺序

上面我们配了两个拦截器,现在我们来测试以下他们的调用顺序

访问某个路径,控制台打印出如下结果
这里写图片描述

  • 在配置文件中,FirstInterceptor拦截器的配置在SecondInterceptor前面
  • 根据结果分析可以得到,preHandle()方法的调用顺序和拦截器的配置顺序一致
  • postHandle()和afterCompletion()方法的调用顺序则是反序

4. 特殊情况

刚刚的例子中,FirstInterceptor和SecondInterceptor两个拦截器的preHandler方法都是return true,因此后面的方面都可以正常执行。

  • 现在假设SecondInterceptor的preHandle返回false,会怎样?我们来看结果截图
    这里写图片描述
  • 从结果中看到,FirstInterceptor 的preHandle先被执行,这没问题
  • 然后执行SecondInterceptor的preHandle,它返回false,因此后续的目标方法都不被执行,但是,FirstInterceptor的afterCompletion方法居然被执行了。
  • 如果从源码分析,可以明白这是为什么,但是对于大多数人来说这太难。
  • 我们从这个结果中总结出一个结论:一个拦截器一旦preHandle被执行return true,那么它就一定要释放资源(之前说过afterCompletion方法用来释放资源)
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值