Java 如何在 Spring Boot 中添加过滤器类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19825946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add a filter class in Spring Boot?
提问by janetsmith
I wonder, if there is any annotation for a Filter
class (for web applications) in Spring Boot? Perhaps @Filter
?
我想知道,Filter
Spring Boot 中的类(对于 Web 应用程序)是否有任何注释?也许@Filter
?
I want to add a custom filter in my project.
我想在我的项目中添加一个自定义过滤器。
The Spring Boot Reference Guidementioned about
FilterRegistrationBean
, but I am not sure how to use it.
Spring Boot 参考指南提到了
FilterRegistrationBean
,但我不确定如何使用它。
回答by Dave Syer
There isn't a special annotation to denote a servlet filter. You just declare a @Bean
of type Filter
(or FilterRegistrationBean
). An example (adding a custom header to all responses) is in Boot's own EndpointWebMvcAutoConfiguration;
没有特殊的注释来表示 servlet 过滤器。您只需声明 a@Bean
类型Filter
(或FilterRegistrationBean
)。一个示例(向所有响应添加自定义标头)在 Boot 自己的EndpointWebMvcAutoConfiguration 中;
If you only declare a Filter
it will be applied to all requests. If you also add a FilterRegistrationBean
you can additionally specify individual servlets and url patterns to apply.
如果您只声明 aFilter
它将应用于所有请求。如果您还添加了FilterRegistrationBean
,则可以另外指定要应用的单个 servlet 和 url 模式。
Note:
笔记:
As of Spring Boot 1.4, FilterRegistrationBean
is not deprecated and simply moved packages from org.springframework.boot.context.embedded.FilterRegistrationBean
to org.springframework.boot.web.servlet.FilterRegistrationBean
从 Spring Boot 1.4 开始,FilterRegistrationBean
没有被弃用,只是将包从org.springframework.boot.context.embedded.FilterRegistrationBean
到org.springframework.boot.web.servlet.FilterRegistrationBean
回答by tegatai
Here is an example of one method of including a custom filter in a Spring Boot MVC application. Be sure to include the package in a component scan:
这是在 Spring Boot MVC 应用程序中包含自定义过滤器的一种方法的示例。确保在组件扫描中包含该包:
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 {}
}
回答by Haim Raman
If you want to setup a third-party filter you can use FilterRegistrationBean
.
For example the equivalent of web.xml
如果要设置第三方过滤器,可以使用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>
These will be the two beans in your @Configuration
file
这些将是您@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();
}
The above was tested with spring-boot 1.2.3
以上是用spring-boot 1.2.3测试的
回答by barryku
There are three ways to add your filter,
可以通过三种方式添加过滤器,
- Annotate your filter with one of the Spring stereotypes such as
@Component
- Register a
@Bean
withFilter
type in Spring@Configuration
- Register a
@Bean
withFilterRegistrationBean
type in Spring@Configuration
- 使用 Spring 构造型之一注释您的过滤器,例如
@Component
- 在 Spring 中注册一个
@Bean
withFilter
类型@Configuration
- 在 Spring 中注册一个
@Bean
withFilterRegistrationBean
类型@Configuration
Either #1 or #2 will do if you want your filter applies to all requests without customization, use #3 otherwise. You don't need to specify component scan for #1 to work as long as you place your filter class in the same or sub-package of your SpringApplication
class. For #3, use along with #2 is only necessary when you want Spring to manage your filter class such as have it auto wired dependencies. It works just fine for me to new my filter which doesn't need any dependency autowiring/injection.
如果您希望过滤器应用于所有请求而无需自定义,则 #1 或 #2 都可以,否则请使用 #3。只要您将过滤器类放在类的相同或子包中,您就不需要为 #1 指定组件扫描即可工作SpringApplication
。对于 #3,仅当您希望 Spring 管理过滤器类(例如让它自动连接依赖项)时,才需要与 #2 一起使用。新我的过滤器对我来说很好用,不需要任何依赖自动装配/注入。
Although combining #2 and #3 works fine, I was surprised it doesn't end up with two filters applying twice. My guess is that Spring combines the two beans as one when it calls the same method to create both of them. In case you want to use #3 alone with authowiring, you can AutowireCapableBeanFactory
. The following is an example,
虽然结合 #2 和 #3 效果很好,但我很惊讶它最终没有应用两次过滤器。我的猜测是,当 Spring 调用相同的方法来创建这两个 bean 时,它会将这两个 bean 合二为一。如果您想单独使用 #3 与 authowiring,您可以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;
}
回答by Lucky
From Spring docs,
从 Spring 文档,
Embedded servlet containers - Add a Servlet, Filter or Listener to an application
嵌入式 servlet 容器 - 向应用程序添加 Servlet、过滤器或侦听器
To add a Servlet, Filter, or Servlet *Listener provide a @Beandefinition for it.
要添加 Servlet、过滤器或 Servlet *Listener,请为其提供@Bean定义。
Eg:
例如:
@Bean
public Filter compressFilter() {
CompressingFilter compressFilter = new CompressingFilter();
return compressFilter;
}
Add this @Bean
config to your @Configuration
class and filter will be registered on startup.
将此@Bean
配置添加到您的@Configuration
类中,过滤器将在启动时注册。
Also you can add Servlets, Filters, and Listeners using classpath scanning,
您也可以使用类路径扫描添加 Servlet、过滤器和侦听器,
@WebServlet, @WebFilter, and @WebListener annotated classes can be automatically registered with an embedded servlet container by annotating a @Configuration class with @ServletComponentScan and specifying the package(s) containing the components that you want to register. By default, @ServletComponentScan will scan from the package of the annotated class.
@WebServlet、@WebFilter 和@WebListener 注释类可以通过使用@ServletComponentScan 注释@Configuration 类并指定包含要注册的组件的包来自动向嵌入式servlet 容器注册。默认情况下,@ServletComponentScan 将从带注释的类的包中进行扫描。
回答by DPancs
Here is an example of my custom Filter class:
这是我的自定义过滤器类的示例:
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);
}
}
And I added it to the Spring boot configuration by adding it to Configuration class as follows:
我通过将它添加到 Configuration 类来将它添加到 Spring boot 配置中,如下所示:
package com.dawson.configuration;
import com.fasterxml.Hymanson.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.Hymanson2ObjectMapperBuilder;
@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;
}
}
回答by Andrei Epure
If you use Spring Boot + Spring Security, you can do that in the security configuration.
如果您使用 Spring Boot + Spring Security,则可以在安全配置中执行此操作。
In the below example, I'm adding a custom filter before the UsernamePasswordAuthenticationFilter (see all the default Spring Security filters and their order).
在下面的示例中,我在 UsernamePasswordAuthenticationFilter 之前添加了一个自定义过滤器(请参阅所有默认的 Spring Security 过滤器及其顺序)。
@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired FilterDependency filterDependency;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(
new MyFilter(filterDependency),
UsernamePasswordAuthenticationFilter.class);
}
}
And the filter class
和过滤器类
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);
}
}
回答by Cwrwhaf
You can use @WebFilter javax.servlet.annotation.WebFilter on a class that implements javax.servlet.Filter
您可以在实现 javax.servlet.Filter 的类上使用 @WebFilter javax.servlet.annotation.WebFilter
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {}
Then use @ServletComponentScan to register
然后使用@ServletComponentScan注册
回答by KayV
Using the @WebFilter annotation, it can be done as follows:
使用@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
}
}
回答by saravanan
Filters are mostly used in logger files it varies according to the logger you using in the project Lemme explain for log4j2:
过滤器主要用于记录器文件,它根据您在项目 Lemme Explain for 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>
Filters are used to restrict the data and i used threshold filter further to restrict the levels of data in the flow I mentioned the levels that can be restricted over there. For your further refrence see the level order of log4j2 - Log4J Levels: ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF
过滤器用于限制数据,我使用阈值过滤器进一步限制流中的数据级别,我提到了可以在那里限制的级别。如需进一步参考,请参阅 log4j2 - Log4J Levels 的级别顺序:ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF