zoukankan      html  css  js  c++  java
  • 16 SpringMVC 拦截器 方法详解 和 多拦截器

    补充:

    interceptor 的执行顺序大致为:
    
    1.请求到达 DispatcherServlet
    2.DispatcherServlet 发送至 Interceptor ,执行 preHandle
    3.请求达到 Controller,返回视图前执行 postHandle
    4.请求结束后,postHandle 执行

    先看下 刚刚拿三个重写的方法(特征已经说了 这里不说)

       @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            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 {
    
        }



    第一个是preHandle 他有三个参数 ,都是我们学过最基本的 请求、响应,至于第三个 handler ,我也不知道 我百度了一下:

    handler,是指controller的@Controller注解下的"完整"方法名, 是包含exception等字段信息的.  emmm...用的不多

    其实呢 preHandle这个方法 主要还是用来判断用户有无权限 或 参数是否正确,这个方法是用的最多的 ,因为每一次请求都要结果他: 下面演示 不合格拦截后跳转到index(或者其他页面):

        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            String Parameter = request.getParameter("init");
            //如果携带参数 init 且 init = yes 的话 那么就放行 不然就转发(或者其他)到index(视图解析器已配置)
            if ("yes".equals(Parameter)){
                return true;
            }else{
                request.getRequestDispatcher("/index.jsp").forward(request,response);
            }
            return false;
        }

    第二个方法 的参数 是第一个一样的 再加一个 ModelAndView ,如果你控制器的方法里 有modelandview 你完全可以吧你携带出去的数据 在这里做更改,但是没必要 ,因为你本来就要带出去还改他干嘛...

    测试一下:

    控制器方法:(modelandview (这里是分离的 我懒得写,都一样的)已携带 data

        @RequestMapping("/show")
       public String show(Model model){
        model.addAttribute("data","成功返回 未被拦截!");    //已携带data
        return "TestJSP";
        }

    拦截器postHandle方法:

        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            //控制器方法那里携带了参数 data ,这里替换掉。
            modelAndView.addObject("data","成功执行 已替换参数 未拦截!");
        }

    允许结果:


    第三个方法没什么好说的  ,前两个是请求和响应,第三个是 Handler 第四个是异常  这个几乎不怎么用。。。。

    暂缺

     


    多拦截器

    我们在声明拦截器的时候 是用  <mvc:interceptors> 然后下面的  <mvc:interceptor>  标签来声明,一个拦截器可以设置拦截指定的控制器 网址。

    因为可以配置多个拦截器 所以呢,如果我配置了多个拦截器 而且 这些拦截器拦截的网址一样的话 那么他有个过滤器执行的先后顺序

    比如现在我有两个拦截器 两个一个  MyHandlerInterceptor 一个是 MyHandlerInterceptor2 ,那么使他们都拦截同一个网址 show :

    拦截器:

    package com.bihu;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class MyHandlerInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("我是拦截器的preHandle方法 我执行了!");
            return true;    //测试先后顺序 放行
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("我是拦截器的postHandle方法 我执行了!");
    
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("我是拦截器的afterCompletion方法 我执行了!");
    
        }
    }

    拦截器2:

    package com.bihu;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class MyHandlerInterceptor2 implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("我是拦截器的preHandle2方法 我执行了!");
            return true;    //测试先后顺序 放行
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("我是拦截器的postHandle2方法 我执行了!");
    
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("我是拦截器的afterCompletion2方法 我执行了!");
    
        }
    }

    然后 拦截器配置(声明):

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.bihu.MyHandlerInterceptor"></bean>
        </mvc:interceptor>
    
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.bihu.MyHandlerInterceptor2"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

    注意啊 连个拦截器都拦截全部的请求(url)

    然后我们直接测试一下 看下打印结果:

    我是拦截器的preHandle方法 我执行了!
    我是拦截器的preHandle2方法 我执行了!
    我是拦截器的postHandle2方法 我执行了!
    我是拦截器的postHandle方法 我执行了!
    我是拦截器的afterCompletion2方法 我执行了!
    我是拦截器的afterCompletion方法 我执行了!

    可以看到 先执行了 :

    拦截器的 pre  ==》拦截器2的pre   ===》

    拦截器2的post ==》 拦截器的 post ==》

    拦截器2 的 after ==》拦截器的 after ==》结束

    其实我们还记得firter过滤器吗,他执行的顺序是在web.xml中定义的顺序,那么其实springmvc也是,至于为什么post方法哪里 拦截器2先执行 是因为 类似于弹栈 (个人觉得 总之顺序就是这样),

    我把他们配置的顺序调换一下:

    <mvc:interceptors>
    
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.bihu.MyHandlerInterceptor2"></bean>
        </mvc:interceptor> 
        
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.bihu.MyHandlerInterceptor"></bean>
        </mvc:interceptor>
    
    </mvc:interceptors>

    执行结果:

    我是拦截器的preHandle2方法 我执行了!
    我是拦截器的preHandle方法 我执行了!
    我是拦截器的postHandle方法 我执行了!
    我是拦截器的postHandle2方法 我执行了!
    我是拦截器的afterCompletion方法 我执行了!
    我是拦截器的afterCompletion2方法 我执行了!

    呐  总之顺序就是这样



    摘抄CSDN博主 这瓜保熟么  链接:https://blog.csdn.net/luzhensmart/article/details/86702671

    那么拦截器和过滤器有什么区别:

    (1)Filter需要在web.xml中配置,依赖于Servlet;
    (2)Interceptor需要在SpringMVC中配置,依赖于框架;
    (3)Filter的执行顺序在Interceptor之前,具体的流程见下图;

    两者的本质区别:拦截器(Interceptor)是基于Java的反射机制,而过滤器(Filter)是基于函数回调。从灵活性上说拦截器功能更强大些,Filter能做的事情,都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类),太细的话,还是建议用interceptor。不过还是根据不同情况选择合适的。

    本文来自博客园,作者:咸瑜,转载请注明原文链接:https://www.cnblogs.com/bi-hu/p/15015068.html

  • 相关阅读:
    洛谷【P1109 学生分组】 题解
    卡特兰数
    并查集
    深度优先搜索DFS;递归
    【71】序列模型和注意力机制
    c/c++ 常用的几个安全函数
    win32 Ui 编程 收集
    vc获取特殊路径(SpecialFolder)
    std::map 自定义排序
    16-----BBS论坛
  • 原文地址:https://www.cnblogs.com/bi-hu/p/15015068.html
Copyright © 2011-2022 走看看