SpringMvc 拦截器 Interceptor

一 简述:

拦截器依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理

关于过滤器的一些用法可以参考这些文章:

  • 在SpringMVC中使用拦截器(interceptor)拦截CSRF攻击(修):https://www.zifangsky.cn/671.html

  • SpringMVC中使用Interceptor+cookie实现在一定天数之内自动登录:https://www.zifangsky.cn/700.html

其中 对于过个拦截器它们之间的执行顺序跟在SpringMVC的配置文件中定义的先后顺序有关

二 根据springmvc流程结合过滤器,拦截器作用位置的分析图如下

三 过滤器与拦截器的区别

       (1)拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
  (2)拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
  (3)拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  (4)拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  (5)在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

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

四 应用场景

1、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
2、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;
3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时 间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
4、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
5、OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。

本质也是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现。

五 实际应用(demo)

1.实现HandlerInterceptor

2.在springmvc配置文件中进行配置(对于aop类的默认在springmvc文件中配置比如切面注解)

六 防止拦截器拦截静态资源

方案一、拦截器中增加针对静态资源不进行过滤(涉及spring-mvc.xml)

  <!-- 释放对静态资源的拦截 -->
<mvc:resources location="/" mapping="/**/*.js"/> 
<mvc:resources location="/" mapping="/**/*.css"/> 
<mvc:resources location="/assets/" mapping="/assets/**/*"/> 
<mvc:resources location="/images/" mapping="/images/*" cache-period="360000"/>
    <!-- 拦截器 -->  
    <mvc:interceptors>
      <mvc:interceptor>  
       <!-- 释放对静态资源的拦截 -->  
       <mvc:mapping path="/**/*"/>
   <mvc:exclude-mapping path="/**/fonts/*"/>
   <mvc:exclude-mapping path="/**/*.css"/>
   <mvc:exclude-mapping path="/**/*.js"/>
   <mvc:exclude-mapping path="/**/*.png"/>
   <mvc:exclude-mapping path="/**/*.gif"/>
   <mvc:exclude-mapping path="/**/*.jpg"/>
   <mvc:exclude-mapping path="/**/*.jpeg"/>
   <mvc:exclude-mapping path="/**/*login*"/>
   <mvc:exclude-mapping path="/**/*Login*"/>      
        <!-- 特定的拦截器 -->
        <bean class="com.fang.interceptor.MyloginInterceptor2" />  
      </mvc:interceptor>

     </mvc:interceptors> 

其它方案可参考网上其它资源。

备注:在使用自定义注解标注切点时,切面不起作用后来发现要将aop标签写在springmvc配置文件里面进行拦截controller

 <!--配置使Spring采用CGLIB代理 -->  
  <aop:aspectj-autoproxy proxy-target-class="true" />  

猜你喜欢

转载自blog.csdn.net/weixin_39494923/article/details/80674076