拦截器
 
 
 
   
 
 
1. 定义
       Spring Web MVC  
  的处理器拦截器类似于 
  Servlet  
  开发中的过滤器 
  Filter 
  ,用于对处理器进行预处理和后处理。
 
 
 
  
 
 
2. 拦截器定义
实现HandlerInterceptor 
  接口即可,如下:
 
 
 
  
 
 
public class HandlerInterceptor1 implements HandlerInterceptor {
 
  
 
   
 
  
     /**
 
  
      * controller执行前调用此方法
 
  
      * 返回true代表继续执行,返回false代表终止执行
 
  
      * 这里可以假如登录校验,,权限拦截等
 
  
      */
 
  
     @Override
 
  
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
 
  
                throws Exception {
 
  
           System.out.println("一号处理器拦截器执行前处理");
 
  
           return true;
 
  
     }
 
  
 
   
 
  
     /**
 
  
      * controller执行后但未返回视图前调用此方法
 
  
      * 这里可以返回用户前对模型数据进行加工处理,比如这里加入公用的信息以便页面显示
 
  
      */
 
  
     @Override
 
  
     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
 
  
                ModelAndView modelAndView) throws Exception {
 
  
           // TODO Auto-generated method stub
 
  
           System.out.println("一号处理器拦截器执行后处理");
 
  
     }
 
  
 
   
 
  
     /**
 
  
      * controller执行后且视图返回后调用此方法
 
  
      * 这里可得到执行controller时的异常信息
 
  
      * 这里可以记录操作日志,资源清理
 
  
      */
 
  
     @Override
 
  
     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
 
  
                throws Exception {
 
  
           // TODO Auto-generated method stub
 
  
           System.out.println("一号完成处理执行后扫尾工作");
 
  
     }
 
  
 
   
 
  
}
 
 
 
  
 
 
 
  
 
 
3. 拦截器配置
1. 针对某种mapping配置拦截器
< 
  bean
 
 
     
  class 
  = 
  "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" 
  >
 
 
     
  < 
  property  
  name 
  = 
  "interceptors" 
  >
 
 
        
  < 
  list 
  >
 
 
            
  < 
  ref  
  bean 
  = 
  "handlerInterceptor1" 
  />
 
 
            
  < 
  ref  
  bean 
  = 
  "handlerInterceptor2" 
  />
 
 
        
  </ 
  list 
  >
 
 
     
  </ 
  property 
  >
 
 
</ 
  bean 
  >
 
 
     
  < 
  bean  
  id 
  = 
  "handlerInterceptor1"  
  class 
  = 
  "springmvc.intercapter.HandlerInterceptor1" 
  />
 
 
     
  < 
  bean  
  id 
  = 
  "handlerInterceptor2"  
  class 
  = 
  "springmvc.intercapter.HandlerInterceptor2" 
  />
 
 
 
  
 
 
 
  
 
 
2. 针对所有mapping配置全局拦截器
 
  
 
 
<!-- 
  拦截器  
  -->
 
 
< 
  mvc:interceptors 
  >
 
 
     
  <!-- 
  多个拦截器 
  , 
  顺序执行  
  -->
 
 
     
  < 
  mvc:interceptor 
  >
 
 
        
  < 
  mvc:mapping  
  path 
  = 
  "/**" 
  />
 
 
        
  < 
  bean  
  class 
  = 
  "cn.itcast.springmvc.filter.HandlerInterceptor1" 
  ></ 
  bean 
  >
 
 
     
  </ 
  mvc:interceptor 
  >
 
 
     
  < 
  mvc:interceptor 
  >
 
 
        
  < 
  mvc:mapping  
  path 
  = 
  "/**" 
  />
 
 
        
  < 
  bean  
  class 
  = 
  "cn.itcast.springmvc.filter.HandlerInterceptor2" 
  ></ 
  bean 
  >
 
 
     
  </ 
  mvc:interceptor 
  >
 
 
</ 
  mvc:interceptors 
  >
 
 
 
  
 
 
4. 正常流程测试
 
  
 
 
3. 代码:
定义两个拦截器分别为: 
  HandlerInterceptor1 
  和 
  HandlerInteptor2 
  ,每个拦截器的 
  preHandler 
  方法都返回 
  true 
  。
 
  
  
  
   
  
   
  
4. 运行流程
HandlerInterceptor1..preHandle..
  
HandlerInterceptor2..preHandle..
  
   
  
HandlerInterceptor2..postHandle..
  
HandlerInterceptor1..postHandle..
  
   
  
HandlerInterceptor2..afterCompletion..
  
HandlerInterceptor1..afterCompletion..
  
   
  
   
  
5. 中断流程测试
1. 代码:
定义两个拦截器分别为:   HandlerInterceptor1 
  和 
  HandlerInteptor2 
  。
  
   
  
   
  
6. 运行流程
HandlerInterceptor1   的 
  preHandler 
  方法返回 
  false 
  , 
  HandlerInterceptor2 
  返回 
  true 
  ,运行流程如下:
  
   
  
HandlerInterceptor1..preHandle..
  
   
  
从日志看出第一个拦截器的   preHandler 
  方法返回 
  false 
  后第一个拦截器只执行了 
  preHandler 
  方法,其它两个方法没有执行,第二个拦截器的所有方法不执行,且 
  controller 
  也不执行了。
  
   
  
   
  
HandlerInterceptor1   的 
  preHandler 
  方法返回 
  true 
  , 
  HandlerInterceptor2 
  返回 
  false 
  ,运行流程如下:
  
   
  
HandlerInterceptor1..preHandle..
  
HandlerInterceptor2..preHandle..
  
HandlerInterceptor1..afterCompletion..
  
   
  
从日志看出第二个拦截器的   preHandler 
  方法返回 
  false 
  后第一个拦截器的 
  postHandler 
  没有执行,第二个拦截器的 
  postHandler 
  和 
  afterCompletion 
  没有执行,且 
  controller 
  也不执行了。
  
   
  
总结:
  
preHandle   按拦截器定义顺序调用
  
postHandler   按拦截器定义逆序调用
  
afterCompletion   按拦截器定义逆序调用
  
   
  
postHandler   在拦截器链内所有拦截器返成功调用
  
afterCompletion   只有 
  preHandle 
  返回 
  true 
  才调用
  
6. 拦截器应用
1. 处理流程
7. 有一个登录页面,需要写一个controller访问页面
8. 登录页面有一提交表单的动作。需要在controller中处理。    
1. 判断用户名密码是否正确
2. 如果正确 想session中写入用户信息
3. 返回登录成功,或者跳转到商品列表
9. 拦截器。    
1. 拦截用户请求,判断用户是否登录
2. 如果用户已经登录。放行
3. 如果用户未登录,跳转到登录页面。
   
  
8. 用户身份认证
   
  
Public class    LoginInterceptor  
  implements    HandlerInterceptor{
  
   
  
       @Override
  
       Public boolean    preHandle(HttpServletRequest request,
  
           HttpServletResponse response, Object handler)    throws    Exception {
  
   
  
          // 
  如果是登录页面则放行
  
          if   (request.getRequestURI().indexOf( 
  "login.action" 
  )>=0){
  
              return true   ;
  
       }
  
       HttpSession session = request.getSession();
  
          // 
  如果用户已登录也放行
  
          if   (session.getAttribute( 
  "user" 
  )!= 
  null   ){
  
              return true   ;
  
       }
  
          // 
  用户没有登录挑战到登录页面
  
        request.getRequestDispatcher(   "/WEB-INF/jsp/login.jsp" 
  ).forward(request, response);
  
       
  
          return false   ;
  
    }
  
}
  
   
  
9. 用户登陆controller
//   登陆页面
  
       @RequestMapping 
  ( 
  "/login" 
  )
  
       public    String login(Model model) 
  throws    Exception{
  
       
  
          return    "login" 
  ;
  
    }
  
    
  
       // 
  登陆提交
  
       // 
  userid   :用户账号, 
  pwd   :密码
  
       @RequestMapping 
  ( 
  "/loginsubmit" 
  )
  
       public    String loginsubmit(HttpSession session,String userid,String pwd) 
  throws    Exception{
  
       
  
          // 
  向 
  session 
  记录用户身份信息
  
       session.setAttribute(   "activeUser" 
  , userid);
  
       
  
          return    "redirect:item/queryItem.action" 
  ;
  
    }
  
    
  
       // 
  退出
  
       @RequestMapping 
  ( 
  "/logout" 
  )
  
       public    String logout(HttpSession session) 
  throws    Exception{
  
       
  
          //session 
  过期
  
       session.invalidate();
  
       
  
          return    "redirect:item/queryItem.action" 
  ;
  
    
  

 
拦截器
   
     
   
1. 定义
       Spring Web MVC     的处理器拦截器类似于 
   Servlet  
   开发中的过滤器 
   Filter 
   ,用于对处理器进行预处理和后处理。
   
    
   
2. 拦截器定义
    实现HandlerInterceptor    接口即可,如下:
   
    
   
public class HandlerInterceptor1 implements HandlerInterceptor {
    
     
    
     /**
    
      * controller执行前调用此方法
    
      * 返回true代表继续执行,返回false代表终止执行
    
      * 这里可以假如登录校验,,权限拦截等
    
      */
    
     @Override
    
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    
                throws Exception {
    
           System.out.println("一号处理器拦截器执行前处理");
    
           return true;
    
     }
    
     
    
     /**
    
      * controller执行后但未返回视图前调用此方法
    
      * 这里可以返回用户前对模型数据进行加工处理,比如这里加入公用的信息以便页面显示
    
      */
    
     @Override
    
     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
    
                ModelAndView modelAndView) throws Exception {
    
           // TODO Auto-generated method stub
    
           System.out.println("一号处理器拦截器执行后处理");
    
     }
    
     
    
     /**
    
      * controller执行后且视图返回后调用此方法
    
      * 这里可得到执行controller时的异常信息
    
      * 这里可以记录操作日志,资源清理
    
      */
    
     @Override
    
     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    
                throws Exception {
    
           // TODO Auto-generated method stub
    
           System.out.println("一号完成处理执行后扫尾工作");
    
     }
    
     
    
}
   
    
   
    
   
3. 拦截器配置     
1. 针对某种mapping配置拦截器
<    bean
   
        class 
   = 
   "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" 
   >
   
        < 
   property  
   name 
   = 
   "interceptors" 
   >
   
           < 
   list 
   >
   
               < 
   ref  
   bean 
   = 
   "handlerInterceptor1" 
   />
   
               < 
   ref  
   bean 
   = 
   "handlerInterceptor2" 
   />
   
           </ 
   list 
   >
   
        </ 
   property 
   >
   
</    bean 
   >
   
        < 
   bean  
   id 
   = 
   "handlerInterceptor1"  
   class 
   = 
   "springmvc.intercapter.HandlerInterceptor1" 
   />
   
        < 
   bean  
   id 
   = 
   "handlerInterceptor2"  
   class 
   = 
   "springmvc.intercapter.HandlerInterceptor2" 
   />
   
    
   
    
   
2. 针对所有mapping配置全局拦截器
    
   
<!--    拦截器  
   -->
   
<    mvc:interceptors 
   >
   
        <!-- 
   多个拦截器 
   , 
   顺序执行  
   -->
   
        < 
   mvc:interceptor 
   >
   
           < 
   mvc:mapping  
   path 
   = 
   "/**" 
   />
   
           < 
   bean  
   class 
   = 
   "cn.itcast.springmvc.filter.HandlerInterceptor1" 
   ></ 
   bean 
   >
   
        </ 
   mvc:interceptor 
   >
   
        < 
   mvc:interceptor 
   >
   
           < 
   mvc:mapping  
   path 
   = 
   "/**" 
   />
   
           < 
   bean  
   class 
   = 
   "cn.itcast.springmvc.filter.HandlerInterceptor2" 
   ></ 
   bean 
   >
   
        </ 
   mvc:interceptor 
   >
   
</    mvc:interceptors 
   >
   
    
   
4. 正常流程测试
    
   
3. 代码:
定义两个拦截器分别为:    HandlerInterceptor1 
   和 
   HandlerInteptor2 
   ,每个拦截器的 
   preHandler 
   方法都返回 
   true 
   。
       
   
    
   
    
   
4. 运行流程
HandlerInterceptor1..preHandle..
   
HandlerInterceptor2..preHandle..
   
    
   
HandlerInterceptor2..postHandle..
   
HandlerInterceptor1..postHandle..
   
    
   
HandlerInterceptor2..afterCompletion..
   
HandlerInterceptor1..afterCompletion..
   
    
   
    
   
5. 中断流程测试     
1. 代码:
定义两个拦截器分别为:    HandlerInterceptor1    和 
   HandlerInteptor2 
   。
   
    
   
    
   
6. 运行流程
HandlerInterceptor1    的    preHandler 
   方法返回 
   false 
   , 
   HandlerInterceptor2 
   返回 
   true 
   ,运行流程如下:
   
    
   
HandlerInterceptor1..preHandle..
   
    
   
从日志看出第一个拦截器的    preHandler    方法返回 
   false 
   后第一个拦截器只执行了 
   preHandler 
   方法,其它两个方法没有执行,第二个拦截器的所有方法不执行,且 
   controller 
   也不执行了。
   
    
   
    
   
HandlerInterceptor1    的    preHandler 
   方法返回 
   true 
   , 
   HandlerInterceptor2 
   返回 
   false 
   ,运行流程如下:
   
    
   
HandlerInterceptor1..preHandle..
   
HandlerInterceptor2..preHandle..
   
HandlerInterceptor1..afterCompletion..
   
    
   
从日志看出第二个拦截器的    preHandler    方法返回 
   false 
   后第一个拦截器的 
   postHandler 
   没有执行,第二个拦截器的 
   postHandler 
   和 
   afterCompletion 
   没有执行,且 
   controller 
   也不执行了。
   
    
   
总结:
   
preHandle    按拦截器定义顺序调用
   
postHandler    按拦截器定义逆序调用
   
afterCompletion    按拦截器定义逆序调用
   
    
   
postHandler    在拦截器链内所有拦截器返成功调用
   
afterCompletion    只有    preHandle 
   返回 
   true 
   才调用
   
6. 拦截器应用     
1. 处理流程
7. 有一个登录页面,需要写一个controller访问页面
8. 登录页面有一提交表单的动作。需要在controller中处理。     
1. 判断用户名密码是否正确
2. 如果正确 想session中写入用户信息
3. 返回登录成功,或者跳转到商品列表
9. 拦截器。     
1. 拦截用户请求,判断用户是否登录
2. 如果用户已经登录。放行
3. 如果用户未登录,跳转到登录页面。
    
   
8. 用户身份认证
    
   
Public class     LoginInterceptor     implements  
   HandlerInterceptor{
   
    
   
        @Override
   
        Public boolean     preHandle(HttpServletRequest request,
   
           HttpServletResponse response, Object handler)     throws     Exception {
   
    
   
           //    如果是登录页面则放行
   
           if    (request.getRequestURI().indexOf( 
   "login.action" 
   )>=0){
   
               return true    ;
   
       }
   
       HttpSession session = request.getSession();
   
           //    如果用户已登录也放行
   
           if    (session.getAttribute( 
   "user" 
   )!= 
   null 
   ){
   
               return true    ;
   
       }
   
           //    用户没有登录挑战到登录页面
   
        request.getRequestDispatcher(    "/WEB-INF/jsp/login.jsp"    ).forward(request, response);
   
       
   
           return false    ;
   
    }
   
}
   
    
   
9. 用户登陆controller
//    登陆页面
   
        @RequestMapping    ( 
   "/login" 
   )
   
        public     String login(Model model) 
   throws  
   Exception{
   
       
   
           return     "login" 
   ;
   
    }
   
    
   
        //    登陆提交
   
        //    userid 
   :用户账号, 
   pwd 
   :密码
   
        @RequestMapping    ( 
   "/loginsubmit" 
   )
   
        public     String loginsubmit(HttpSession session,String userid,String pwd) 
   throws  
   Exception{
   
       
   
           //    向 
   session 
   记录用户身份信息
   
       session.setAttribute(    "activeUser"    , userid);
   
       
   
           return     "redirect:item/queryItem.action" 
   ;
   
    }
   
    
   
        //    退出
   
        @RequestMapping    ( 
   "/logout" 
   )
   
        public     String logout(HttpSession session) 
   throws  
   Exception{
   
       
   
           //session    过期
   
       session.invalidate();
   
       
   
           return     "redirect:item/queryItem.action" 
   ;