Filter
Spring Boot 中的类(用于 Web 应用程序)是否有任何注释?也许@Filter
?
我想在我的项目中添加一个自定义过滤器。
Spring Boot 参考指南中提到了
FilterRegistrationBean
,但我不知道如何使用它。
Filter
Spring Boot 中的类(用于 Web 应用程序)是否有任何注释?也许@Filter
?
我想在我的项目中添加一个自定义过滤器。
Spring Boot 参考指南中提到了
FilterRegistrationBean
,但我不知道如何使用它。
如果要设置第三方过滤器,可以使用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.3 测试的。
这是在 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 {}
}
添加过滤器的三种方法,
@Component
@Bean
with类型Filter
@Configuration
@Bean
with类型FilterRegistrationBean
@Configuration
如果您希望过滤器适用于所有请求而无需自定义,则 #1 或 #2 都可以,否则使用 #3。只要您将过滤器类放在类的相同或子包中,您就不需要为#1 指定组件扫描SpringApplication
。对于#3,仅当您希望 Spring 管理您的过滤器类(例如让它自动连接依赖项)时,才需要与 #2 一起使用。它对我来说工作得很好,不需要任何依赖自动装配/注入的新过滤器。
尽管将#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;
}
没有特殊的注释来表示 servlet 过滤器。您只需声明 a@Bean
类型Filter
(或FilterRegistrationBean
)。一个示例(向所有响应添加自定义标头)在 Boot 自己的EndpointWebMvcAutoConfiguration中;
如果您只声明 a Filter
,它将应用于所有请求。如果您还添加了一个FilterRegistrationBean
,您可以另外指定要应用的单个 servlet 和 url 模式。
笔记:
从 Spring Boot 1.4 开始,FilterRegistrationBean
不推荐使用,只是将包org.springframework.boot.context.embedded.FilterRegistrationBean
从org.springframework.boot.web.servlet.FilterRegistrationBean
更新:2017-12-16:
在 Spring Boot 1.5.8.RELEASE 中有两种简单的方法可以做到这一点,并且不需要 XML。
第一种方式:
如果您没有任何特定的 URL 模式,您可以像这样使用 @Component(完整的代码和详细信息在这里https://www.surasint.com/spring-boot-filter/):
@Component
public class ExampleFilter implements Filter {
...
}
第二种方式:
如果你想使用 URL 模式,你可以像这样使用@WebFilter(完整的代码和细节在这里https://www.surasint.com/spring-boot-filter-urlpattern/):
@WebFilter(urlPatterns = "/api/count")
public class ExampleFilter implements Filter {
...
}
但是您还需要在 @SpringBootApplication 类中添加 @ServletComponentScan 注释:
@ServletComponentScan
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
...
}
注意@Component 是 Spring 的注解,但 @WebFilter 不是。@WebFilter 是 Servlet 3 注释。
两种方式,您只需要pom.xml中的基本 Spring Boot 依赖项(不需要显式的 Tomcat 嵌入式 jasper)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
</parent>
<groupId>com.surasint.example</groupId>
<artifactId>spring-boot-04</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
WARNING:第一种方式,如果Spring Boot中的Controller返回一个JSP文件,请求会通过两次过滤。
而在第二种方式中,请求只会通过一次过滤器。
我更喜欢第二种方式,因为它更类似于Servlet 规范中的默认行为。
您可以在此处查看更多测试日志:https ://www.surasint.com/spring-boot-webfilter-instead-of-component/
这是我的自定义过滤器类的示例:
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 Boot 配置中,如下所示:
package com.dawson.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;
}
}
从 Spring 文档中,
嵌入式 servlet 容器 - 将 Servlet、过滤器或侦听器添加到应用程序
要添加 Servlet、Filter 或 Servlet *Listener,请为其提供@Bean 定义。
例如:
@Bean
public Filter compressFilter() {
CompressingFilter compressFilter = new CompressingFilter();
return compressFilter;
}
将此@Bean
配置添加到您的@Configuration
类中,过滤器将在启动时注册。
您还可以使用类路径扫描添加 Servlet、过滤器和侦听器,
@WebServlet、@WebFilter 和@WebListener 注释的类可以通过使用@ServletComponentScan 注释@Configuration 类并指定包含要注册的组件的包来自动注册到嵌入式servlet 容器。默认情况下,@ServletComponentScan 将从注解类的包中进行扫描。
我们有大约四种不同的选项来使用 Spring 注册过滤器。
首先,我们可以创建一个 Spring bean 实现Filter或扩展HttpFilter:
@Component
public class MyFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
// Implementation details...
chain.doFilter(request, response);
}
}
其次,我们可以创建一个扩展GenericFilterBean的 Spring bean :
@Component
public class MyFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
//Implementation details...
chain.doFilter(currentRequest, servletResponse);
}
}
或者,我们可以使用FilterRegistrationBean类:
@Configuration
public class FilterConfiguration {
private final MyFilter myFilter;
@Autowired
public FilterConfiguration(MyFilter myFilter) {
this.myFilter = myFilter;
}
@Bean
public FilterRegistrationBean<MyFilter> myFilterRegistration() {
FilterRegistrationBean<DateLoggingFilter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(myFilter);
filterRegistrationBean.setUrlPatterns(Collections.singletonList("/*"));
filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST);
filterRegistrationBean.setOrder(Ordered.LOWEST_PRECEDENCE - 1);
return filterRegistrationBean;
}
}
最后,我们可以将@WebFilter注释与@ServletComponentScan一起使用:
@WebFilter(urlPatterns = "/*", dispatcherTypes = {DispatcherType.REQUEST})
public class MyFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
// Implementation details...
chain.doFilter(request, response);
}
}
如果您使用 Spring Boot + Spring Security,则可以在安全配置中执行此操作。
在下面的示例中,我在 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);
}
}
和过滤器类
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);
}
}
使用@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
}
}
此过滤器还将帮助您允许跨源访问
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "20000");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");
if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
public void destroy() {}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
步骤 1:通过实现Filter接口创建一个过滤器组件。
@Component
public class PerformanceFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
...
...
}
}
第 2 步:使用 FilterRegistrationBean 将此过滤器设置为 URI 模式。
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<PerformanceFilter> perfFilter() {
FilterRegistrationBean<PerformanceFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new PerformanceFilter());
registration.addUrlPatterns("/*");
return registration;
}
}
您可以参考此链接以获取完整的应用程序。
你需要两个主要的东西:
添加@ServletComponentScan
到您的主类
您可以在其中添加一个名为 filter 的包。您创建一个Filter
具有以下内容的类:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestFilter implements Filter {
// whatever field you have
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
// Whatever implementation you want
try {
chain.doFilter(req, res);
} catch(Exception e) {
e.printStackTrace();
}
}
public void init(FilterConfig filterConfig) {
}
public void destroy() {
}
}
这更像是一个建议而不是答案,但如果您在 Web 应用程序中使用 Spring MVC,那么最好使用 Spring HandlerInterceptor 而不是 Filter。
它可以做同样的工作,但也
@Component
public class SecurityInterceptor implements HandlerInterceptor {
private static Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
request.getSession(true);
if(isLoggedIn(request))
return true;
response.getWriter().write("{\"loggedIn\":false}");
return false;
}
private boolean isLoggedIn(HttpServletRequest request) {
try {
UserSession userSession = (UserSession) request.getSession(true).getAttribute("userSession");
return userSession != null && userSession.isLoggedIn();
} catch(IllegalStateException ex) {
return false;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
private HandlerInterceptor securityInterceptor;
@Autowired
public void setSecurityInterceptor(HandlerInterceptor securityInterceptor) {
this.securityInterceptor = securityInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(securityInterceptor).addPathPatterns("/**").excludePathPatterns("/login", "/logout");
}
}
我在这里看到了很多答案,但我没有尝试任何一个。我刚刚按照以下代码创建了过滤器。
import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = "/Admin")
@Configuration
public class AdminFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("happened");
}
@Override
public void destroy() {
}
}
我保留了剩余的 Spring Boot 应用程序。
利用:
@WebFilter(urlPatterns="/*")
public class XSSFilter implements Filter {
private static final org.apache.log4j.Logger LOGGER = LogManager.getLogger(XSSFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("Initiating XSSFilter... ");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpRequestWrapper requestWrapper = new HttpRequestWrapper(req);
chain.doFilter(requestWrapper, response);
}
@Override
public void destroy() {
LOGGER.info("Destroying XSSFilter... ");
}
}
您可以在实现 javax.servlet.Filter 的类上使用 @WebFilter javax.servlet.annotation.WebFilter:
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
}
然后使用@ServletComponentScan 进行注册。
您还可以通过使用@WebFilter
和实现来制作过滤器Filter
。会的。
@Configuration
public class AppInConfig
{
@Bean
@Order(1)
public FilterRegistrationBean aiFilterRegistration()
{
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new TrackingFilter());
registration.addUrlPatterns("/**");
registration.setOrder(1);
return registration;
}
@Bean(name = "TrackingFilter")
public Filter TrackingFilter()
{
return new TrackingFilter();
}
}
我看到了Vasily Komarov的回答。这是一种类似的方法,但使用抽象的HandlerInterceptorAdapter类而不是使用HandlerInterceptor。
这是一个例子......
@Component
public class CustomInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
}
}
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Autowired
private CustomInterceptor customInterceptor ;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(customInterceptor );
}
}
过滤器,顾名思义,用于对对资源的请求或对资源的响应进行过滤,或两者兼而有之。Spring Boot 提供了一些选项来在 Spring Boot 应用程序中注册自定义过滤器。让我们看看不同的选项。
1.定义Spring Boot过滤器和调用顺序
实现Filter接口以在 Spring Boot 中创建一个新的过滤器。
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("########## Initiating Custom filter ##########");
}
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
LOGGER.info("Logging Request {} : {}", request.getMethod(), request.getRequestURI());
// Call next filter in the filter chain
filterChain.doFilter(request, response);
LOGGER.info("Logging Response :{}", response.getContentType());
}
@Override
public void destroy() {
// TODO: 7/4/2018
}
}
让我们快速看一下上面代码中的一些重点
@Component注解注册的过滤器。
要以正确的顺序触发过滤器,我们需要使用@Order注释。
@Component
@Order(1)
public class CustomFirstFilter implements Filter {
}
@Component
@Order(2)
public class CustomSecondFilter implements Filter {
}
在上面的代码中,CustomFirstFilter 将在 CustomSecondFilter 之前运行。
数字越小,优先级越高
2. URL 模式
如果基于约定的映射不够灵活,我们可以使用FilterRegistrationBean来完全控制应用程序。在这里,不要对过滤器类使用@Component注释,而是使用FilterRegistrationBean注册过滤器。
public class CustomURLFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomURLFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("########## Initiating CustomURLFilter filter ##########");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
LOGGER.info("This Filter is only called when request is mapped for /customer resource");
// Call the next filter in the filter chain
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
使用FilterRegistrationBean注册自定义过滤器。
@Configuration
public class AppConfig {
@Bean
public FilterRegistrationBean < CustomURLFilter > filterRegistrationBean() {
FilterRegistrationBean < CustomURLFilter > registrationBean = new FilterRegistrationBean();
CustomURLFilter customURLFilter = new CustomURLFilter();
registrationBean.setFilter(customURLFilter);
registrationBean.addUrlPatterns("/greeting/*");
registrationBean.setOrder(2); // Set precedence
return registrationBean;
}
}
众所周知,Spring Boot 是一种开发 Web 应用程序或独立应用程序的绝妙方式,只需最少的配置和自以为是的设置。
这就是我在 Spring Boot 应用程序中实现 Web 过滤器开发的方式
我的 SpringBootApp 规格:
Spring Boot 版本:2.0.4.RELEASE
Java 版本:8.0
Servlet 规范:Servlet 3.0(强制和重要)
我以以下方式声明了我的 Web 过滤器,遵循 Servlet 规范 3.0
这是将过滤器定义为替代基于web.xml的定义的编程方式。
“@Webfilter”注解将在部署期间由容器处理。将根据配置创建 Filter 类,并将其应用于 URL 模式 javax.servlet.Servlets 和 javax.servlet.DispatcherTypes。
要完全避免 Web.xml 并实现“可部署”WebApp:
要将 Spring Boot 应用程序部署为“传统 WAR”,应用程序类应扩展 SpringBootServletInitializer。
笔记:
SpringBootServletInitializer 是参考 Servlet 3.0+ 规范的web.xml的“程序化实现” ,需要实现 WebApplicationInitializer。
因此,SpringBootApplication 不需要“web.xml”作为其应用程序类(在扩展 SpringBootServletInitializer 之后)。它扫描
注解@ServletComponentScan
此注解可以扫描带有@WebFilter、@WebListener 和@WebServlet 注释的Web 组件的基础包。
由于嵌入式容器不支持@WebServlet、@WebFilter 和@WebListener 注解,Spring Boot 在很大程度上依赖于嵌入式容器,引入了这个新的注解@ServletComponentScan 来支持一些使用这三个注解的依赖JAR 文件。
仅在使用嵌入式 Servlet 容器时执行扫描。
以下是我的 Spring Boot 应用程序类定义:
自定义 Servlet 初始化器:
这里:我定义了一个自定义类:“ServletInitializer”,它扩展了 Class: SpringBootServletInitializer。
如前所述,SpringBootServletInitializer 负责扫描注解:
因此 Spring Boot 应用程序类应该
首先,添加@ServletComponentScan
到您的 SpringBootApplication 类。
@ServletComponentScan
public class Application {
其次,创建一个扩展过滤器或第三方过滤器类的过滤器文件,并添加@WebFilter
到该文件中,如下所示:
@Order(1) //optional
@WebFilter(filterName = "XXXFilter", urlPatterns = "/*",
dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD},
initParams = {@WebInitParam(name = "confPath", value = "classpath:/xxx.xml")})
public class XXXFilter extends Filter{
对于我已经完成的任何配置类中的 Spring Boot:
@Bean
public OncePerRequestFilter myFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
AuthUser authUser = SecurityUtil.safeGet(); // applied after secutiry filters
...
filterChain.doFilter(request, response);
}
};
}
就是这样,不需要任何注册。另请参阅什么是 OncePerRequestFilter?
过滤器主要用于记录器文件。它根据您在项目中使用的记录器而有所不同。
让我解释一下 log4j2:
<Filters>
<!-- It prevents an 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>
过滤器用于限制数据,我进一步使用阈值过滤器来限制流中数据的级别。我提到了那里可以限制的级别。
如需进一步参考,请参阅 log4j2 - Log4J Levels 的级别顺序:ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF