2017.3.31 spring mvc教程(三)拦截器

学习的博客:http://elf8848.iteye.com/blog/875830/

我项目中所用的版本:4.2.0。博客的时间比较早,11年的,学习的是Spring3 MVC。不知道版本上有没有变化比较大的功能。

spring mvc教程(三)拦截器

1.Spring中的拦截器

(1)拦截器接口

Spring提供了拦截器接口。实现这个接口或继承这个类,就能实现自己的拦截器。

1 org.springframework.web.servlet.HandlerInterceptor接口
2 org.springframework.web.servlet.handler.HandlerInterceptorAdapter适配器
1 public class MyInteceptor implements HandlerInterceptor {     
2     //3 } 

HandlerInteceptor有3个方法:分别实现预处理、后处理(调用了Service并返回ModelAndView,但未进行页面渲染)、返回处理(已经渲染了页面)。

1 在preHandle中,可以进行编码、安全控制等处理;
2 在postHandle中,有机会修改ModelAndView;
3 在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录。 

参数中的Object handler是下一个拦截器。

1 //Action之前执行
2  public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler);
3  
4 //生成视图之前执行
5  public void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,ModelAndView modelAndView);
6  
7 //最后执行,可用于释放资源
8  public void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)

(2)拦截器的执行过程

注意点:

1 spring mvc 没有总的拦截器,即不能对所有的请求进行拦截。
2 spring mvc 的拦截器属于HandlerMapping级别。
3 可以有多个HandlerMapping,每个HandlerMapping可以有自己的拦截器。
4 HandlerMapping的执行顺序按照order值从小到大。

执行过程:当一个请求按Order值从小到大,顺序执行HandlerMapping接口的实现类时,哪一个先有返回,那就可以结束了,后面的HandlerMapping就不走了,本道工序就完成了。就转到下一道工序了。

1 <!--没找到处理器,就不会执行拦截。-->
2 请求 --> HandlerMapping  --> 寻找对应的处理器 --> 执行拦截器 --> 目标处理器

(3)拦截器的配置

方案1:(近似)总拦截器,拦截所有url

<mvc:interceptors/>会为每一个HandlerMapping,注入一个拦截器。总有一个HandlerMapping是可以找到处理器的,最多也只找到一个处理器,所以这个拦截器总会被执行的。起到了总拦截器的作用。

缺点:如果是REST风格的URL,静态资源也会被拦截。

1 <mvc:interceptors>  
2     <bean class="com.app.mvc.MyInteceptor" />  
3 </mvc:interceptors>  

方案2:(近似)总拦截器,拦截匹配url

只是比方案1多了一句 url 匹配。所以缺点也是同样的:如果是REST风格的URL,静态资源也会被拦截。

1 <mvc:interceptors >    
2     <mvc:interceptor>    
3           <mvc:mapping path="/user/*" /> <!-- /user/*  -->    
4           <bean class="com.mvc.MyInteceptor"></bean>    
5       </mvc:interceptor>    
6  </mvc:interceptors>    

方案3HandlerMapping上的拦截器

前面提过,如果配置了<mvc:annotation-driven />,spring会自动注册两个bean:DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter 。这种情况下,就无法配置在handlerMapping上的拦截器了。所以去掉<mvc:annotation-driven />,而是手工配置这两个bean,精确的指定拦截器。

1 <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">       
2     <property name="interceptors">       
3          <list>       
4              <bean class="com.mvc.MyInteceptor"></bean>      
5          </list>       
6   </property>       
7 </bean>   
原文地址:https://www.cnblogs.com/lyh421/p/6652464.html