zoukankan      html  css  js  c++  java
  • SpringMVC 拦截器的使用

    拦截器主要用于拦截用户请求,并做相应的处理,十分常用。

    拦截器的常见用法:

    • 判断用户是否登录。比如购物网站用户将商品添加到购物车时,用拦截器判断用户是否登录,如未登录,则不能将商品添加到购物车(转到登录页面)。
    • 进行权限验证。验证已登录的用户是否有相应的操作权限。
    • 记录请求信息的日志。

    拦截器的使用步骤

    (1)编写拦截器类

    实现拦截器有2种方式:

    • 实现HandlerInterceptor接口(常用),或继承HandlerInterceptor接口的实现类
    • 实现WebRequestInterceptor接口,或继承WebRequestInterceptor接口的实现类

    HandlerInterceptor接口的三个方法:

    • boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

          在controller中的业务方法之前执行,返回值表示是否有后续操作。

          true——继续执行后续操作;

          fasle——不再执行后续操作,即不再执行此拦截器的代码、不再执行后续的其它拦截器,不再调用controller中的业务方法来处理请求。

    • void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)

        在controller中业务方法调用之后、视图解析之前执行。

        可对Model、View作出进一步修改。

    • void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

        在视图渲染结束之后执行,即在整个请求完成后执行,可以做一些资源清理、日志记录的工作。

    三个方法对应在三个时间点进行拦截处理。一般我们只使用preHandler()。

    完整的执行流程:

    • 调用preHandle(),如果返回true,继续往下执行;如果返回false,至此结束。
    • 调用controller中的业务方法
    • 调用postHandle()
    • 解析视图,渲染视图
    • 调用afterCompletion()

     

    示例    将商品加入购物车,用拦截器验证用户是否已登录

    新建包com.chy.interceptor,包下新建类LoginInterceptor:

    public class LoginInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //session中有user的信息就通过,否则给出提示信息,重定向到登录页面
            HttpSession session = request.getSession();
            //登录成功时要将user放到session中
            User user = (User)session.getAttribute("user");
            if(user!=null)
                return true;
            //转发到登录页面
            request.setAttribute("msg","您尚未登录,请先登录!");
            request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
            return false;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
        }
    
    }

    (2)在spring mvc的配置文件中配置要使用的拦截器

        <!--配置要使用的拦截器-->
        <mvc:interceptors>
    
             <!--一个interceptor配置一个拦截器 -->
            <mvc:interceptor>
                <!-- 要拦截的请求,**表示拦截该地址下的所有请求 -->
                <mvc:mapping path="/product/purchase/**" />
                <!-- 使用的拦截器类 -->
                <bean class="com.chy.interceptor.LoginInterceptor" />
            </mvc:interceptor>
    
            <mvc:interceptor>
                <!--拦截所有对controller中业务方法的请求-->
                <mvc:mapping path="/**" />
                <!--可指定不拦截的请求-->
                <mvc:exclude-mapping path=""/>
                <bean class="" />
            </mvc:interceptor>
    
        </mvc:interceptors>

    拦截器是在业务方法调用前后进行拦截,拦截的前提是要调用业务方法,即拦截器只拦截对controller中业务方法的请求,不拦截对视图的直接请求。

    <mvc:mapping />指定要拦截的业务方法,<mvc:exclude-mapping />指定<mvc:mapping />中的哪些路径不被拦截。

    有顺序要求:

            <mvc:mapping path="" />
            <mvc:exclude-mapping path=""/>
            <bean class="" />

    <mvc:exclude-mapping />可选。


    多个拦截器的执行顺序

    去的时候拦截器的执行顺序,和配置文件中拦截器的前后顺序一致。

    回来的时候拦截器的执行顺序,和去的时候相反。

    比如:

        <!--配置要使用的拦截器-->
        <mvc:interceptors>
             <!--拦截器1 -->
            <mvc:interceptor></mvc:interceptor>
            <!--拦截器2-->
            <mvc:interceptor></mvc:interceptor>
        </mvc:interceptors>

    假设这2个拦截器都拦截相同的请求。

    去的时候依次执行:拦截器1的preHandler()、拦截器2的preHandler(),和配置顺序相同;

    回来的时候依次执行:拦截器2的postHandler()、拦截器1的postHandler();和配置顺序相反;

    再次回来的时候依次执行:拦截器2的afterCompletion()、拦截器1的afterCompletion(),和配置顺序相反。

  • 相关阅读:
    ansible 使用密码登录
    shell脚本报错:-bash: xxx: /bin/bash^M: bad interpreter: No such file or directory
    配置永久生效(登陆shell和非登陆shell)、I/O重定向、Here Docunmet 此处文档、管道、tee
    Navicat for PostgreSQL 序列详解
    flask第十五篇——Response
    Centos防火墙及SELINUX关闭
    linux查看网卡信息的几种方法(命令)
    Python之在函数中调用import语句
    python基础_格式化输出(%用法和format用法)
    Python中怎样简单地用一行写if-then语句?
  • 原文地址:https://www.cnblogs.com/chy18883701161/p/12250781.html
Copyright © 2011-2022 走看看