• SpringBoot中过滤器与拦截器的区别


    SpringBoot中过滤器与拦截器的区别
    过滤器和拦截器的区别:
    ①拦截器是基于java的反射机制的,而过滤器是基于函数回调。
    ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
    ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
    ④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
    ⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
    ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

    AsyncHandlerInterceptor与OncePerRequestFilter的区别

    过滤器中OncePerRequestFilter的用法
    过滤器是基于函数回调,
    过滤器依赖与servlet容器,
    过滤器则可以对几乎所有的请求起作用,
    过滤器不能访问action上下文、值栈里的对象
    过滤器只能在容器初始化时被调用一次
    过滤器不可以获取IOC容器中的各个bean

    /**
     * token过滤器 验证token有效性   (正在运行启作用) @Order(1)为多个过滤器的排序号
     */
    @Component
    @Order(1)
    public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
        @Autowired
        private TokenService tokenService;
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
                throws ServletException, IOException {
            LoginUser loginUser = tokenService.getLoginUser(request);
            if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(SecurityUtils.getToken())) {
                tokenService.verifyToken(loginUser);
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, null);
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
            chain.doFilter(request, response);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    拦截器AsyncHandlerInterceptor的用法
    拦截器是基于java的反射机制的
    拦截器不依赖与servlet容器
    拦截器只能对action请求起作用
    拦截器可以访问action上下文、值栈里的对象
    在action的生命周期中,拦截器可以多次被调用
    拦截器可以获取IOC容器中的各个bean

    WebMvcConfig.java
    必须标注@Configuration才启作用

    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 WebMvcConfig implements WebMvcConfigurer
    {
        /** 不需要拦截地址 */
        public static final String[] excludeUrls = { "/system/login", "/system/logout", "/system/refresh", "/system/ping" };
    
        @Override
        public void addInterceptors(InterceptorRegistry registry)
        {
            registry.addInterceptor(getHeaderInterceptor())
                    .addPathPatterns("/**")
                    .excludePathPatterns(excludeUrls)
                    .order(-10);
        }
    
        /**
         * 自定义请求头拦截器
         */
        public HeaderInterceptor getHeaderInterceptor()
        {
            return new HeaderInterceptor();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    HeaderInterceptor.java

    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.servlet.AsyncHandlerInterceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 自定义请求头拦截器,将Header数据封装到线程变量中方便获取
     * 注意:此拦截器会同时验证当前用户有效期自动刷新有效期
     */
    public class HeaderInterceptor implements AsyncHandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            if (!(handler instanceof HandlerMethod)) {
                return true;
            }
    
            SecurityContextHolder.setTenantId(ServletUtils.getHeader(request, SecurityConstants.DETAILS_TENANT_ID));
            SecurityContextHolder.setDevice(ServletUtils.getHeader(request, SecurityConstants.DETAILS_DEVICE));
            SecurityContextHolder.setUserId(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USER_ID));
            SecurityContextHolder.setUserName(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USERNAME));
            SecurityContextHolder.setUserKey(ServletUtils.getHeader(request, SecurityConstants.USER_KEY));
    
            String token = SecurityUtils.getToken();
            if (StringUtils.isNotEmpty(token)) {
                LoginUser loginUser = AuthUtil.getLoginUser(token);
                if (StringUtils.isNotNull(loginUser)) {
                    AuthUtil.verifyLoginUserExpire(loginUser);
                    SecurityContextHolder.set(SecurityConstants.LOGIN_USER, loginUser);
                }
            }
            return true;
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            SecurityContextHolder.remove();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    CAD进阶练习(六)、CAD创建块后图形依然保持原状?
    git上传项目的基本步骤与一些问题
    一起来学Kotlin:概念:17. Kotlin Extension Function / Method (扩展函数)
    Flink中的时间和窗口操作
    2023最新SSM计算机毕业设计选题大全(附源码+LW)之java智慧社区管理系统jby69
    阿里十五位顶级架构师联合编写的《微服务架构解析手册》大厂面试必问
    1045 快速排序
    动态负载均衡
    独孤思维:没学会走就要跑,你只能一辈子是穷b
    Eclipse ADT常用快捷键
  • 原文地址:https://blog.csdn.net/hsg77/article/details/133948599