太原要做网站的公司,最近一周的重大热点新闻,在线商城,科技有限公司名称大全1. 问题描述 首先编写一个Filter类并通过Component放入spring容器中#xff0c;通过实现jakarta.servlet中提供的Filter接口完成过滤器的创建#xff0c;代码如下。
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import org.springframework.st…1. 问题描述 首先编写一个Filter类并通过Component放入spring容器中通过实现jakarta.servlet中提供的Filter接口完成过滤器的创建代码如下。
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import org.springframework.stereotype.Component;
import java.io.IOException;
Component
public class MyFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}Overridepublic void destroy() {Filter.super.destroy();}Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println(filter 前置.....);filterChain.doFilter(servletRequest, servletResponse);System.out.println(filter 后置.....);}
}
为了将过滤器配置到目标路径下通常有两种方法 使用servlet提供的WebFilter注解完成过滤路径的配置。
Component
WebFilter(urlPatterns /api/*,filterName myFilterName)
public class MyFilter implements Filter {代码同上省略
} 使用spring boot推荐的配置类FilterRegistrationBean完成过滤路径的配置。
笔者在使用WebFilter注解进行过滤路径配置时发现所有路径下的请求都被过滤了不受WebFilter注解中的参数控制而使用spring推荐的配置类方法则不会出现这个问题。
2. 问题分析
WebFilter、WebServlet 和 WebListener 等与Filter相关的注解均是在Servlet 容器中spring容器中并没有这些注解所以即使在Filter类中加上WebFilter注解并配置好路径参数spring工程中也读不到这个配置spring会使用spring配置类的配置如果spring配置类中没有对Filter进行配置就会使用默认配置即针对所以路径进行过滤所以才会出现以上现象使用WebFilter配置类过滤路径但Filter还是会对所有路径进行过滤。
3. 解决方案 3.1 spring配置类 最简单的解决方案就是不使用WebFilter注解对过滤路径进行配置而是使用spring推荐的配置类的方式进行配置。
Configuration // 专门对 springMVC 底层做一些配置
public class MySpringMVCConfig implements WebMvcConfigurer{Autowiredprivate MyFilter myFilter;Beanpublic FilterRegistrationBean getFilter1Registration() {FilterRegistrationBean filterRegistrationBean new FilterRegistrationBean();filterRegistrationBean.setFilter(this.myFilter);//设置过滤器名称和路径在过滤器类写了的话这里不用重复写filterRegistrationBean.setName(filter);filterRegistrationBean.addUrlPatterns(/api/*);//设置过滤器执行顺序数字越小越早进行过滤也可设置为负数filterRegistrationBean.setOrder(1);return filterRegistrationBean;}}
3.2 WebFilter注解
如果非要使用WebFilter注解的话
第一步需要把WebFilter添加到容器中因为spring容器中并没有WebFilter的注解这个注解在servlet容器中故需要在启动类中添加ServletComponentScan 注解启用 Servlet 容器扫描 WebFilter、WebServlet 和 WebListener 注解将这些组件注册到 Servlet 容器中。
SpringBootApplication
ServletComponentScan
public class SpringmvcRestfulCrudApplication {public static void main(String[] args) {SpringApplication.run(SpringmvcRestfulCrudApplication.class, args);}
}
增加此注解后WebFilter就成功进入到Serlet容器中并生效了能够根据读取WebFilter中的配置对配置内的路径进行过滤。但如果访问的是WebFilter配置内的路径程序会对此路径进行两次过滤如果访问的路径不在WebFilter配置内则依然会被过滤一次。 这是因为在Filter类中添加了Component注解如果同时使用Component和ServletComponentScan这两个注解Filter 类既会被 Spring 容器实例化也会被 Servlet 容器实例化导致被实例化两次。spring容器中实例化的Filter依然使用配置类的FilterRegistrationBean配置如果没有则使用默认配置进行所有路径过滤。 所以就会出现在启动类增加ServletComponentScan注解后如果路径在WebFilter配置内的访问会被过滤两次一次是servlet容器实例化的Filter过滤的另一次是spring容器实例化的Filter过滤。如果路径不在WebFilter配置内依然会被过滤一次这一次是spring容器中的Filter使用了默认配置进行的全路径过滤。
第二步为了使用WebFilter进行配置不受spring容器实例化的Filter干扰即将Filter类中的Component注解删掉Filter类不受spring容器控制也不会进行实例化这样就不会有两个实例化的Filter进行相互干扰了。
//Component 不放到spring容器中管理
WebFilter(urlPatterns /api/*,filterName myFilterName)
public class MyFilter implements Filter {代码同上省略
} 4 总结 综上所述如果在spring boot工程中使用过滤器Filter推荐在配置类中使用FilterRegistrationBean进行过滤路径配置并在Filter类中添加Component将Filter类加载到spring容器中。 如果要使用WebFilter进行过滤路径的配置则需要在启动类中添加ServletComponentScan注解启用Servlet容器扫描WebFilter注解并删除Filter类中的Component注解防止spring实例化的Filter与Servlet容器实例化的Filter冲突。 今后读者在使用过程中只要意识到自己过滤器Filter是由spring实例化的还是servlet实例化的两个实例化的Filter所使用的配置方式不一样要使用对应的配置方式。万万不可同时使用Component注解和ServletComponetScan注解。