如何在Spring Boot中添加一个filter类?

我想知道,如果在Spring Boot中有一个Filter类(用于Web应用程序)的注释吗? 也许@Filter

我想在我的项目中添加一个自定义filter。

Spring Boot Reference Guide提到了FilterRegistrationBean ,但是我不确定如何使用它。

如果你想设置第三方filter,你可以使用FilterRegistrationBean 。 例如相当于web.xml

 <filter> <filter-name>SomeFilter</filter-name> <filter-class>com.somecompany.SomeFilter</filter-class> </filter> <filter-mapping> <filter-name>SomeFilter</filter-name> <url-pattern>/url/*</url-pattern> <init-param> <param-name>paramName</param-name> <param-value>paramValue</param-value> </init-param> </filter-mapping> 

这些将是@Configuration文件中的两个bean

 @Bean public FilterRegistrationBean someFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(someFilter()); registration.addUrlPatterns("/url/*"); registration.addInitParameter("paramName", "paramValue"); registration.setName("someFilter"); registration.setOrder(1); return registration; } public Filter someFilter() { return new SomeFilter(); } 

以上是用spring-boot 1.2.3testing的

下面是一个在Spring Boot MVC应用程序中包含自定义filter的方法示例。 确保在包含扫描的组件中包含该软件包:

 package com.dearheart.gtsc.filters; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; @Component public class XClacksOverhead implements Filter { public static final String X_CLACKS_OVERHEAD = "X-Clacks-Overhead"; @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.setHeader(X_CLACKS_OVERHEAD, "GNU Terry Pratchett"); chain.doFilter(req, res); } @Override public void destroy() {} @Override public void init(FilterConfig arg0) throws ServletException {} } 

没有特别的注释来表示一个servletfilter。 您只需声明Filter (或FilterRegistrationBean )types的@Bean 。 一个例子(为所有响应添加一个自定义标题)在Boot自己的EndpointWebMvcAutoConfiguration中 ;

如果你只声明一个Filter ,它将被应用于所有请求。 如果您还添加了FilterRegistrationBean ,则可以额外指定要应用的单个servlet和url模式。

注意:

从Spring Boot 1.4开始, FilterRegistrationBean不被弃用,只需将org.springframework.boot.context.embedded.FilterRegistrationBean包移动到org.springframework.boot.web.servlet.FilterRegistrationBean

有三种方法来添加你的filter,

  1. 使用@Component的Spring @Component型来注释你的filter
  2. 在Spring @Configuration注册一个Filtertypes的@Bean
  3. 在Spring @Configuration使用FilterRegistrationBeantypes注册一个@Bean

如果您希望您的filter适用于所有请求而无需自定义,请使用#1或#2,否则请使用#3。 只要将filter类放在SpringApplication类的相同或子包中,就不需要为#1指定组件扫描。 对于#3,只有当你希望Springpipe理你的filter类,比如拥有自动连接的依赖关系时,才需要使用#2。 它对我来说工作得很好,我的新filter不需要任何依赖自动assembly/注入。

尽pipe#2和#3的组合工作正常,我很惊讶,它不会结束两个filter应用两次。 我的猜测是,当Spring调用相同的方法来创build它们时,Spring将这两个bean合并为一个。 如果你想单独使用#3自动显示,你可以AutowireCapableBeanFactory 。 以下是一个例子,

 private @Autowired AutowireCapableBeanFactory beanFactory; @Bean public FilterRegistrationBean myFilter() { FilterRegistrationBean registration = new FilterRegistrationBean(); Filter myFilter = new MyFilter(); beanFactory.autowireBean(myFilter); registration.setFilter(myFilter); registration.addUrlPatterns("/myfilterpath/*"); return registration; } 

从春季文档,

embedded式servlet容器 – 将Servlet,Filter或Listener添加到应用程序中

要添加Servlet,Filter或Servlet * Listener,请为其提供@Bean定义。

例如:

 @Bean public Filter compressFilter() { CompressingFilter compressFilter = new CompressingFilter(); return compressFilter; } 

将这个@Beanconfiguration添加到你的@Configuration类中,filter将在启动时注册。

也可以使用类path扫描来添加Servlet,filter和监听器,

@WebServlet,@WebFilter和@WebListener带批注的类可以通过使用@ServletComponentScan注释@Configuration类并指定包含要注册的组件的包来自动向embedded式servlet容器注册。 默认情况下,@ServletComponentScan将从注释类的包中扫描。

以下是我的自定义Filter类的示例:

 package com.dawson.controller.filter; import org.springframework.stereotype.Component; import org.springframework.web.filter.GenericFilterBean; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class DawsonApiFilter extends GenericFilterBean { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; if (req.getHeader("x-dawson-nonce") == null || req.getHeader("x-dawson-signature") == null) { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setContentType("application/json"); httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Required headers not specified in the request"); return; } chain.doFilter(request, response); } } 

我通过将它添加到Configuration类中来将它添加到Spring引导configuration中,如下所示:

 package com.lyrahealth.configuration; import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module; import com.dawson.controller.filter.DawsonApiFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; @SpringBootApplication public class ApplicationConfiguration { @Bean public FilterRegistrationBean dawsonApiFilter() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new DawsonApiFilter()); // In case you want the filter to apply to specific URL patterns only registration.addUrlPatterns("/dawson/*"); return registration; } } 

使用@WebFilter注释,可以按如下方式完成:

 @WebFilter(urlPatterns = {"/*" }) public class AuthenticationFilter implements Filter{ private static Logger logger = Logger.getLogger(AuthenticationFilter.class); @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest arg0, ServletResponse response, FilterChain chain) throws IOException, ServletException { logger.info("checking client id in filter"); HttpServletRequest request = (HttpServletRequest) arg0; String clientId = request.getHeader("clientId"); if (StringUtils.isNotEmpty(clientId)) { chain.doFilter(request, response); } else { logger.error("client id missing."); } } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } } 

您可以对实现javax.servlet.Filter的类使用@WebFilter javax.servlet.annotation.WebFilter

 @WebFilter(urlPatterns = "/*") public class MyFilter implements Filter {} 

然后使用@ServletComponentScan进行注册

如果您使用Spring Boot + Spring Security,则可以在安全configuration中执行此操作。

在下面的示例中,我在UsernamePasswordAuthenticationFilter之前添加了一个自定义filter(请参阅所有默认的Spring Securityfilter及其顺序 )。

 @EnableWebSecurity class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired FilterDependency filterDependency; @Override protected void configure(HttpSecurity http) throws Exception { http .addFilterBefore( new MyFilter(filterDependency), UsernamePasswordAuthenticationFilter.class); } } 

和filter类

 class MyFilter extends OncePerRequestFilter { private final FilterDependency filterDependency; public MyFilter(FilterDependency filterDependency) { this.filterDependency = filterDependency; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // filter filterChain.doFilter(request, response); } } 

filter主要用于logging器文件,它根据您在项目中使用的logging器而有所不同Lemme解释为log4j2:

 <Filters> <!-- It prevents error --> <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/> <!-- It prevents debug --> <ThresholdFilter level="debug" onMatch="DENY" onMismatch="NEUTRAL" /> <!-- It allows all levels except debug/trace --> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> </Filters> 

filter用于限制数据,我使用阈值filter进一步限制stream量中的数据级别,我提到了可以在那里限制的级别。 为了进一步参考,请参阅log4j2的级别顺序 – Log4J级别:ALL> TRACE> DEBUG> INFO> WARN> ERROR> FATAL> OFF