zoukankan      html  css  js  c++  java
  • SpringBoot 2.x (7):拦截器

     类似以前SpringMVC的拦截器,但也有一些区别

    SpringBoot的拦截器有两种方式:

    第一种方式:过时的方式,适用于SpringBoot1.x的方式

    package org.dreamtech.springboot.interceptor;
    
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    @SuppressWarnings("deprecation")
    public class CustomWebMvcConfigurer extends WebMvcConfigurerAdapter {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/test/*/**");
            super.addInterceptors(registry);
        }
    }

    第二种方式:基于Java8与Spring5的方式

    原理:在WebMvcConfigurer接口中定义了默认方法,利用Java8新特性:接口中可以写方法

    package org.dreamtech.springboot.interceptor;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class CustomWebMvcConfigurer implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/login/*/**");
            WebMvcConfigurer.super.addInterceptors(registry);
        }
    }

    LoginInterceptor:只是实现了三个基本方法,分别打印一句话,了解执行顺序:

    package org.dreamtech.springboot.interceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    public class LoginInterceptor implements HandlerInterceptor {
        /**
         * 拦截之前调用(进入Controller之前)
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            System.out.println("[ preHandle LoginInterceptor ]");
            return HandlerInterceptor.super.preHandle(request, response, handler);
        }
    
        /**
         * 调用方法之后,视图渲染之前
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                ModelAndView modelAndView) throws Exception {
            System.out.println("[ postHandle LoginInterceptor ]");
            HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
        }
    
        /**
         * 完成拦截之后,用于清理资源
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("[ afterCompletion LoginInterceptor ]");
            HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        }
    }

    Controller:

    package org.dreamtech.springboot.controller;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class DemoController {
    
        @RequestMapping("/login/account")
        private Object account() {
            Map<String, Object> modelMap = new HashMap<String, Object>();
            modelMap.put("money", 1000);
            System.out.println("[ account DemoController ]");
            return modelMap;
        }
    }

    访问localhost:8080/login/account打印情况如下:

    [ preHandle LoginInterceptor ]
    [ account DemoController ]
    [ postHandle LoginInterceptor ]
    [ afterCompletion LoginInterceptor ]

    如果没有以上打印,要注意这几点:

    1.是否有@Configuration注解

    2.是否将拦截路径写成/xxx/*/**,如果是/xxx/*/*就会拦截失败

    同样地,我们可以添加多个拦截器

            registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/login/*/**");
            registry.addInterceptor(new TestInterceptor()).addPathPatterns("/test/*/**");
            registry.addInterceptor(new DemoInterceptor()).addPathPatterns("/demo/*/**");

    或者链式调用:拦截所有路径,但不包括/login

    registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");

    多个拦截器的调用顺序:可以理解为包裹的方式

    package org.dreamtech.springboot.interceptor;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class CustomWebMvcConfigurer implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/login/*/**");
            registry.addInterceptor(new DemoInterceptor()).addPathPatterns("/login/*/**");
            WebMvcConfigurer.super.addInterceptors(registry);
        }
    }

    DemoInterceptor和LoginInterceptor内容基本一致

    最终的打印:

    [ preHandle LoginInterceptor ]
    [ preHandle DemoInterceptor ]
    [ account DemoController ]
    [ postHandle DemoInterceptor ]
    [ postHandle LoginInterceptor ]
    [ afterCompletion DemoInterceptor ]
    [ afterCompletion LoginInterceptor ]

    最后:

    Filter和Interceptor的区别:

    1.Filter基于Servlet,而Interceptor不依赖于Servlet容器

    2.Filter只在容器被初始化的时候被调用一次,Interceptor次数没有限制

    3.Interceptor基于AOP思想,Filter基于doFilter方法

    两者的执行顺序:

    过滤前->拦截前->Controller->拦截后->过滤后

  • 相关阅读:
    iOS objc_msgSend 报错解决方案
    不再以讹传讹,GET和POST的真正区别
    HTTP Get请求URL最大长度
    [转]浅论ViewController的加载 -- 解决 viewDidLoad 被提前加载的问题(pushViewController 前执行)
    ASIHTTPRequest-断点续传需要原网站支持!
    iOS关于error can't allocate region的一点发现
    Xcode 5.1.1 与 Xcode 6.0.1 的共存之路(建议大家在升级Xcode 6.0.1 的时候保留Xcode 5.1.1)
    监测uitableview 向上滑动和向下滑动的事件
    Xcode5和6共存时,如何发布应用到商店
    利用MPMoviePlayerViewController 播放视频 iOS
  • 原文地址:https://www.cnblogs.com/xuyiqing/p/10824902.html
Copyright © 2011-2022 走看看