拦截器

一、基本概念

1. 拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。
2.拦截器是在面向切面编程中应用的,就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于JAVA的反射机制。拦截器不是在web.xml中配置,而是比如struts在struts.xml中配置,或者spring MVC中的mvc配置文件中配置
3. 拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
4. 大部分时候,拦截器方法都是通过代理的方式来调用的。Struts 2的拦截器实现相对简单。当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器。
5. 自定义拦截器的步骤
1)自定义一个实现了Interceptor(HandlerInterceptorAdapter)接口的类,或者继承抽象类AbstractInterceptor

2)在配置文件中注册定义的拦截器

3)在需要使用Action中引用上述定义的拦截器,为了方便也可以将拦截器定义为默认的拦截器,这样在不加特殊说明的情况下,所有的Action都被这个拦截器拦截。
6. 应用场景
1)日志记录,可以记录请求信息的日志,以便进行信息监控、信息统计等。

2)权限检查:如登陆检测,进入处理器检测是否登陆,如果没有直接返回到登陆页面。

3)性能监控:典型的是慢日志

4)通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale等其他request请求中的数据

5)OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。本质也是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现

二、常用方法

1. preHandle
1) 预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器(如我们上一章的Controller实现)

2) 返回值:true表示继续流程(如调用下一个拦截器或处理器),false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应
2. postHandle
1) 后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null
3. afterCompletion
1) 整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion	
4. 运行流程图
1) 正常流程

在这里插入图片描述

2) 中断流程

在这里插入图片描述


三、代码示例

1. 写一个自定义拦截器继承HandlerInterceptorAdapter
public class MyInterceptor extends HandlerInterceptorAdapter {  // 此处一般继承HandlerInterceptorAdapter适配器即可  

    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
        System.out.println("===========MyInterceptor preHandle");  
        return true;  
    }  

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

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

}  
2. 在spring.xml中或者springMVC的配置文件中
<mvc:interceptors> 
       <mvc:interceptor>
               <!--  
                   /**的意思是所有文件夹及里面的子文件夹 
                   /*是所有文件夹,不含子文件夹 
                   /是web项目的根目录
                 --> 
               <mvc:mapping path="/**" /> 
               <!-- 需排除拦截的地址 -->  
               <!--  <mvc:exclude-mapping path="/userController/login"/>  -->
               <bean id="commonInterceptor" class="org.shop.interceptor.MyInterceptor"></bean> <!--这个类就是我们自定义的Interceptor -->
      </mvc:interceptor> 
      <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法  -->
</mvc:interceptors>

四、过滤器与拦截器的区别

在这里插入图片描述

1. 过滤器可以简单的理解为“取你所想取”,过滤器关注的是web请求(包括静态资源也是请求);拦截器可以简单的理解为“拒你所想拒”,拦截器关注的是方法调用,比如拦截敏感词汇
1)拦截器是基于java反射机制来实现的,而过滤器是基于函数回调来实现的。(有人说,拦截器是基于动态代理来实现的)

2)拦截器不依赖servlet容器,过滤器依赖于servlet容器

3)拦截器只对Action起作用,过滤器可以对所有请求起作用

4)拦截器可以访问Action上下文和值栈中的对象,过滤器不能

5)在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时调用一次

6)拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑

7)过滤器包裹住servlet,servlet包裹住拦截器(也就是触发时机不同)

8)拦截器功在对请求权限鉴定方面确实很有用处,第三方的远程调用每个请求都需要参与鉴定,所以这样做非常方便,而且他是很独立的逻辑,这样做让业务逻辑代码很干净

参考网址

Java三大器之拦截器(Interceptor)的实现原理及代码示例

第五章 处理器拦截器详解——跟着开涛学SpringMVC

SpringMVC 拦截器实现原理和登录实现

拦截器和过滤器的区别

java web 过滤器跟拦截器的区别和使用

注:文章是经过参考其他的文章然后自己整理出来的,有可能是小部分参考,也有可能是大部分参考,但绝对不是直接转载,觉得侵权了我会删,我只是把这个用于自己的笔记,顺便整理下知识的同时,能帮到一部分人。
ps : 有错误的还望各位大佬指正,小弟不胜感激

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值