• 【SpringMVC】拦截器


    一、概述

    1.1 拦截器的异常场合

    • 用户请求到DispatherServlet中,DispatherServlet调用HandlerMapping查找Handler,HandlerMapping返回一个拦截的链儿(多个拦截),springmvc中的拦截器是通过HandlerMapping发起的。
    • 在企业开发,使用拦截器实现用户认证(用户登陆后进行身份校验拦截),用户权限拦截。

    1.2 拦截器中的方法

    public class HandlerInterceptor1 implements HandlerInterceptor {
    
        //在执行handler之前来执行的
        //用于用户认证校验、用户权限校验
        @Override
        public boolean preHandle(HttpServletRequest request,
                HttpServletResponse response, Object handler) throws Exception {
            
            System.out.println("HandlerInterceptor1...preHandle");
            
            //如果返回false表示拦截不继续执行handler,如果返回true表示放行
            return false;
        }
        //在执行handler返回modelAndView之前来执行
        //如果需要向页面提供一些公用 的数据或配置一些视图信息,使用此方法实现 从modelAndView入手
        @Override
        public void postHandle(HttpServletRequest request,
                HttpServletResponse response, Object handler,
                ModelAndView modelAndView) throws Exception {
            System.out.println("HandlerInterceptor1...postHandle");
            
        }
        //执行handler之后执行此方法
        //作系统 统一异常处理,进行方法执行性能监控,在preHandle中设置一个时间点,在afterCompletion设置一个时间,两个时间点的差就是执行时长
        //实现 系统 统一日志记录
        @Override
        public void afterCompletion(HttpServletRequest request,
                HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("HandlerInterceptor1...afterCompletion");
        }
    
    }
    

    二、示例

    2.1 定义两个拦截器

    2.2 配置拦截器

    • 配置全局的拦截器,DispatcherServlet将配置的全局拦截器加载到所有的HandlerMapping。
    • 在springmvc.xml中配置:
        <!--拦截器 -->
        <mvc:interceptors>
            <!--多个拦截器,顺序执行 -->
            <mvc:interceptor>
                <mvc:mapping path="/**" />
                <bean class="com.hao.ssm.controller.interceptor.HandlerInterceptor1"></bean>
            </mvc:interceptor>
            <mvc:interceptor>
                <mvc:mapping path="/**" />
                <bean class="com.hao.ssm.controller.interceptor.HandlerInterceptor2"></bean>
            </mvc:interceptor> 
            
            
        </mvc:interceptors>
    

    2.3 执行顺序

    • 执行preHandle是顺序执行。
    • 执行postHandle、afterCompletion是倒序执行
    • 如果preHandle不放行,postHandle、afterCompletion都不执行。
    • 只要有一个拦截器不放行,controller不能执行完成
    • 只有前边的拦截器preHandle方法放行,下边的拦截器的preHandle才执行。

    三、拦截器应用

    3.1 需求

    • 用户访问系统的资源(url),如果用户没有进行身份认证,进行拦截,系统跳转登陆页面,如果用户已经认证通过,用户可以继续访问系统 的资源。

    3.2 用户登陆及退出功能开发

    @Controller
    public class LoginController {
        
        
        //用户登陆提交方法
        @RequestMapping("/login")
        public String login(HttpSession session, String usercode,String password)throws Exception{
            
            //调用service校验用户账号和密码的正确性
            //..
            
            //如果service校验通过,将用户身份记录到session
            session.setAttribute("usercode", usercode);
            //重定向到商品查询页面
            return "redirect:/items/queryItems.action";
        }
        
        //用户退出
        @RequestMapping("/logout")
        public String logout(HttpSession session)throws Exception{
            
            //session失效
            session.invalidate();
            //重定向到商品查询页面
            return "redirect:/items/queryItems.action";
            
        }
        
    
    }
    

    3.3 用户身份认证校验拦截器

    • 拦截实现思路:

    3.4 编写拦截器

    public class LoginInterceptor implements HandlerInterceptor {
    
        //在执行handler之前来执行的
        //用于用户认证校验、用户权限校验
        @Override
        public boolean preHandle(HttpServletRequest request,
                HttpServletResponse response, Object handler) throws Exception {
            
            //得到请求的url
            String url = request.getRequestURI();
            
            //判断是否是公开 地址
            //实际开发中需要公开 地址配置在配置文件中
            //...
            if(url.indexOf("login.action")>=0){
                //如果是公开 地址则放行
                return true;
            }
            
            //判断用户身份在session中是否存在
            HttpSession session = request.getSession();
            String usercode = (String) session.getAttribute("usercode");
            //如果用户身份在session中存在放行
            if(usercode!=null){
                return true;
            }
            //执行到这里拦截,跳转到登陆页面,用户进行身份认证
            request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
            
            //如果返回false表示拦截不继续执行handler,如果返回true表示放行
            return false;
        }
        //在执行handler返回modelAndView之前来执行
        //如果需要向页面提供一些公用 的数据或配置一些视图信息,使用此方法实现 从modelAndView入手
        @Override
        public void postHandle(HttpServletRequest request,
                HttpServletResponse response, Object handler,
                ModelAndView modelAndView) throws Exception {
            System.out.println("HandlerInterceptor1...postHandle");
            
        }
        //执行handler之后执行此方法
        //作系统 统一异常处理,进行方法执行性能监控,在preHandle中设置一个时间点,在afterCompletion设置一个时间,两个时间点的差就是执行时长
        //实现 系统 统一日志记录
        @Override
        public void afterCompletion(HttpServletRequest request,
                HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("HandlerInterceptor1...afterCompletion");
        }
    
    }
    
    
    • 在配置文件中配置拦截器
    <!--拦截器 -->
        <mvc:interceptors>
            <!--多个拦截器,顺序执行 -->
            <!-- <mvc:interceptor>
                <mvc:mapping path="/**" />
                <bean class="com.hao.ssm.controller.interceptor.HandlerInterceptor1"></bean>
            </mvc:interceptor>
            <mvc:interceptor>
                <mvc:mapping path="/**" />
                <bean class="com.hao.ssm.controller.interceptor.HandlerInterceptor2"></bean>
            </mvc:interceptor> -->
            
            <mvc:interceptor>
                <!-- /**可以拦截路径不管多少层 -->
                <mvc:mapping path="/**" />
                <bean class="com.hao.ssm.controller.interceptor.LoginInterceptor"></bean>
            </mvc:interceptor>
        </mvc:interceptors>
    
  • 相关阅读:
    遇到shell重定向的一个奇怪问题:'消失'的标准输入!
    步步深入:MySQL架构总览->查询执行流程->SQL解析顺序
    [来自妹纸的挑战]-展开/还原多层链表
    【Shell】Linux 一行 多命令
    【Shell】通配符与特殊符号
    【Shell】变量的取用、删除、取代与替换
    【LeetCode】Find Minimum in Rotated Sorted Array 在旋转数组中找最小数
    【LeetCode】Maximum Product Subarray 求连续子数组使其乘积最大
    【LeetCode】Reverse Words in a String 反转字符串中的单词
    【面试题】比给定数大的最小数
  • 原文地址:https://www.cnblogs.com/haoworld/p/springmvc-lan-jie-qi.html
Copyright © 2020-2023  润新知