• SpringMVC学习--拦截器


    • 简介

      Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。

    • 拦截器定义

      定义拦截器,实现HandlerInterceptor接口。接口中提供三个方法。

     1 public class HandlerInterceptor1 implements HandlerInterceptor {
     2 
     3     
     4     //进入 Handler方法之前执行
     5     //用于身份认证、身份授权
     6     //比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
     7     @Override
     8     public boolean preHandle(HttpServletRequest request,
     9             HttpServletResponse response, Object handler) throws Exception {
    10         
    11         //return false表示拦截,不向下执行
    12         //return true表示放行
    13         return false;
    14     }
    15 
    16     //进入Handler方法之后,返回modelAndView之前执行
    17     //应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
    18     @Override
    19     public void postHandle(HttpServletRequest request,
    20             HttpServletResponse response, Object handler,
    21             ModelAndView modelAndView) throws Exception {
    22         
    23         
    24     }
    25 
    26     //执行Handler完成执行此方法
    27     //应用场景:统一异常处理,统一日志处理
    28     @Override
    29     public void afterCompletion(HttpServletRequest request,
    30             HttpServletResponse response, Object handler, Exception ex)
    31             throws Exception {
    32         
    33         
    34     }
    35 
    36 }
    • 拦截器配置

      1、针对HandlerMapping配置

      springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该拦截器。

     1 <bean
     2     class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
     3     <property name="interceptors">
     4         <list>
     5             <ref bean="handlerInterceptor1"/>
     6             <ref bean="handlerInterceptor2"/>
     7         </list>
     8     </property>
     9 </bean>
    10     <bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
    11     <bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>

      2、全局的拦截器

     1 <!--拦截器 -->
     2 <mvc:interceptors>
     3     <!--多个拦截器,顺序执行 -->
     4     <mvc:interceptor>
     5         <mvc:mapping path="/**"/>
     6         <bean class="com.luchao.springmvc.filter.HandlerInterceptor1"></bean>
     7     </mvc:interceptor>
     8     <mvc:interceptor>
     9         <mvc:mapping path="/**"/>
    10         <bean class="com,luchao.springmvc.filter.HandlerInterceptor2"></bean>
    11     </mvc:interceptor>
    12 </mvc:interceptors>
    • 拦截测试

      编写两个拦截器,进行拦截测试。

      1、两个拦截器都放行

    1 HandlerInterceptor1...preHandle
    2 HandlerInterceptor2...preHandle
    3 
    4 HandlerInterceptor2...postHandle
    5 HandlerInterceptor1...postHandle
    6 
    7 HandlerInterceptor2...afterCompletion
    8 HandlerInterceptor1...afterCompletion

      总结:

      preHandle方法按顺序执行,

      postHandle和afterCompletion按拦截器配置的逆向顺序执行。

      2、拦截器1放行,拦截器2不放行

    1 HandlerInterceptor1...preHandle
    2 HandlerInterceptor2...preHandle
    3 HandlerInterceptor1...afterCompletion

      总结:

      拦截器1放行,拦截器2 preHandle才会执行。

      拦截器2 preHandle不放行,拦截器postHandle和afterCompletion不会执行。

      只要有一个拦截器不放行,postHandle不会执行。

      3、拦截器1不放行,拦截器2不放行

    1 HandlerInterceptor1...preHandle

      拦截器1 preHandle不放行,postHandle和afterCompletion不会执行。

      拦截器1 preHandle不放行,拦截器2不执行。

      总结:

      根据测试结果,对拦截器应用。比如:统一日志处理拦截器,需要该 拦截器preHandle一定要放行,且将它放在拦截器链接中第一个位置。比如:登陆认证拦截器,放在拦截器链接中第一个位置。权限校验拦截器,放在登陆认证拦截器之后。(因为登陆通过后才校验权限)

    • 拦截器应用(实现登陆认证)

      1、controller方法

    @Controller
    public class LoginController {
    
        // 登陆
        @RequestMapping("/login")
        public String login(HttpSession session, String username, String password)
                throws Exception {
    
            // 调用service进行用户身份验证
            // ...
    
            // 在session中保存用户身份信息
            session.setAttribute("username", username);
            // 重定向到商品列表页面
            return "redirect:/items/queryItems.action";
        }
    
        // 退出
        @RequestMapping("/logout")
        public String logout(HttpSession session) throws Exception {
    
            // 清除session
            session.invalidate();
    
            // 重定向到商品列表页面
            return "redirect:/items/queryItems.action";
        }
    
    }

      2、登陆认证拦截器

     1 public class LoginInterceptor implements HandlerInterceptor {
     2 
     3     
     4     //进入 Handler方法之前执行
     5     //用于身份认证、身份授权
     6     //比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
     7     @Override
     8     public boolean preHandle(HttpServletRequest request,
     9             HttpServletResponse response, Object handler) throws Exception {
    10         
    11         //获取请求的url
    12         String url = request.getRequestURI();
    13         //判断url是否是公开 地址(实际使用时将公开 地址配置配置文件中)
    14         //这里公开地址是登陆提交的地址
    15         if(url.indexOf("login.action")>=0){
    16             //如果进行登陆提交,放行
    17             return true;
    18         }
    19         
    20         //判断session
    21         HttpSession session  = request.getSession();
    22         //从session中取出用户身份信息
    23         String username = (String) session.getAttribute("username");
    24         
    25         if(username != null){
    26             //身份存在,放行
    27             return true;
    28         }
    29         
    30         //执行这里表示用户身份需要认证,跳转登陆页面
    31         request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
    32         
    33         //return false表示拦截,不向下执行
    34         //return true表示放行
    35         return false;
    36     }

     

  • 相关阅读:
    Oracle数据库安装
    [转]卡西欧手表调日期正确方法
    python密码处理(可用于生产模式)
    [转]python对json的相关操作
    [转]Python中的with…as…
    Python标准库--os模块
    我的github代码添加
    Python正则表达式+自创口诀
    自己总结python用xlrdxlwt读写excel
    CentOS安装+配置+远程
  • 原文地址:https://www.cnblogs.com/lcngu/p/5518268.html
Copyright © 2020-2023  润新知