如何在Spring Boot中添加过滤器类?


229

我想知道,FilterSpring Boot中的类(对于Web应用程序)是否有任何注释?也许@Filter吧?

我想在我的项目中添加一个自定义过滤器。

《 Spring Boot参考指南》提到了有关 FilterRegistrationBean,但是我不确定如何使用它。


注意,用@WebFilter添加的过滤器的行为不像Servlet规范中的真实过滤器。这将是一个在其他许多Spring Bean之后被调用的Spring Bean,而不像任何Servlet代码之前的真实过滤器那样。
lrxw

你能告诉我你的确切要求吗?如果您想要ComponentScan的过滤器类,那么该“ @ ComponentScan.Filter”有一个注释
Keaz

Answers:


159

如果您要设置第三方过滤器,则可以使用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进行了测试


1
如果我想添加多个过滤器怎么办?@Opal
verystrongjoe 2015年

8
只需添加一个额外的@Bean public FilterRegistrationBean AdditionalFilterRegistration()
Haim Raman

如何知道应用过滤器的顺序?
BeepDog

7
FilterRegistrationBean.setOrder
Haim Raman

someFilter()直接调用该方法时,您不需要filter bean 。
WST

117

这是在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 {}

}

4
过滤器应该在某处注册吗?
gstackoverflow

1
当我尝试这种方法时,Filter是作为bean创建的,甚至被注入到其他类中,但是init()方法没有运行。可能,init()仅在“正常”注册中有效,而不能通过spring容器工作。我认为,可以使用PostConstruct代替init(),但是我没有尝试过,因为我拒绝将Filter声明为Spring bean。
包尔赞

使用这种方法的过滤器排序又如何呢?
帕维尔·弗拉索夫

我们如何从ServletResponse获取RS主体?
user2602807

1
需要注意的重要一件事是,bean的名称(基于类名)不应与Spring Bean相同。例如,您可能很想创建一个MetricsFilter,但是该bean将被同名的Spring执行器bean遮盖。艰难地学习了这一点……
kinbiko '17

78

没有特殊的注释来表示servlet过滤器。您只需声明一个@Bean类型Filter(或FilterRegistrationBean)。在Boot自己的EndpointWebMvcAutoConfiguration中有一个示例(向所有响应中添加自定义标头);

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

注意:

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


您介意告诉我如何在build.gradle中包括相应的条目吗?我添加了以下内容,但未进行编译:
ProvidedCompile

2
Spring Boot不适用于Servlet 2.5,并且对JSP的支持还不多。我并不是真正的平地机,所以我不知道您要做什么。“编译”有什么问题?如果您仅依靠“ spring-boot-starter-web”,它会起作用吗?(尽管我认为这些问题与原始问题无关,所以也许您应该再次发布新问题?)
Dave Syer

我通过实现Filter接口添加了一个过滤器,但是Eclipse无法找到该接口。所以我试图弄清楚如何将其添加到classpath进行编译。
珍妮史密斯,

1
是的,您当然需要Filter在类路径上。通常,我只会使用spring-boot-starter-web来引入所有相关的依赖关系(例如here)。
Dave Syer

关于其他响应的详细信息,您也可以使用@Component注释Filter类,该类将被自动注册(对于所有URL)。
雅各布·霍尔(JakubHolý)

72

有三种添加过滤器的方法,

  1. 使用Spring构造型之一注释您的过滤器,例如 @Component
  2. 在Spring @Bean中用Filter类型注册@Configuration
  3. 在Spring @Bean中用FilterRegistrationBean类型注册@Configuration

如果您希望过滤器应用于所有请求而无需自定义,则#1或#2都可以,否则请使用#3。只要将过滤器类放在类的相同或子包中,就无需指定组件扫描才能使#1起作用SpringApplication。对于#3,仅当您希望Spring管理过滤器类(例如,使其具有自动连线的依赖项)时,才需要与#2一起使用。不需要任何依赖项自动装配/注入的新过滤器,它对我来说就很好用。

尽管将#2和#3组合起来可以很好地工作,但令我惊讶的是,最后并没有应用两次两次的滤镜。我的猜测是,当Spring调用相同的方法来创建两个bean时,会将两个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;
    }

极好的答案。感谢您详细介绍所有选项,并涵盖了如何Filter在使用时自动FilterRegistrationBean
接线

好答案。这正是我所想要的!
haykart


31

更新: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>

警告:第一种方式,如果Spring Boot中的Controller返回到JSP文件,则请求将两次通过过滤器。

而以第二种方式,请求将仅通过过滤器一次。

我更喜欢第二种方式,因为它与Servlet规范中的默认行为更相似(https://docs.oracle.com/cd/E19879-01/819-3669/6n5sg7b0b/index.html

您可以在这里查看更多测试日志https://www.surasint.com/spring-boot-webfilter-instead-of-component/


我已经看到Filter在applicationContext启动期间接口被多次调用。有什么办法只能执行一次吗?
Pra_A

@PAA您是从我的示例中得出的意思吗?
Surasin Tancharoen

20

这是我的自定义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引导配置中:

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;
    }
}

14

从Spring文档中,

嵌入式Servlet容器-向应用程序添加Servlet,过滤器或侦听器

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

例如:

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

将此@Bean配置添加到您的@Configuration班级,过滤器将在启动时注册。

您还可以使用类路径扫描来添加Servlet,过滤器和侦听器,

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



7

如果您使用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);
    }
}

5

使用@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

    }

}

3
还添加@ServletComponentScan
Justas

5

我们大约有四个不同的选项来使用Spring注册一个过滤器

首先,我们可以创建一个实现Filter或扩展HttpFilter的Spring bean :

@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);
    }
}

使用哪个过滤器,为什么?
Pra_A

3

它不是一个建议,而是一个答案,但是,如果您在Web应用程序中使用Spring MVC,那么最好的方法是使用Spring HandlerInterceptor而不是Filter

它可以完成相同的工作,而且-可以与ModelAndView一起使用-可以在请求处理之前或之后或请求完成之后调用其方法。
-可以轻松测试

1实现HandlerInterceptor接口,并在类中添加@Component批注

@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 {

    }
}

2配置拦截器

@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");
    }

}

简洁大方!谢谢
MrMins '19

3

此过滤器还将帮助您允许跨源访问

@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

    }

}

2

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

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

然后使用@ServletComponentScan进行注册


2

我在这里看到了很多答案,但没有尝试任何答案。我已经按照下面的代码创建了过滤器。

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应用程序。


2

您需要做两件事:-添加@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() {}
}

1

您还可以通过使用@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();
        }   
    }

1

过滤器的名称建议用于对资源的请求或对资源的响应(或两者)进行过滤。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/18
 }
}

让我们快速看一下上面代码中的一些要点

  • @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 next filter in the filter chain
  filterChain.doFilter(request, response);
 }

 @Override
 public void destroy() {

 }
}

使用FilterRegistrationBean注册自定义Filter 。

@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;
 }
}

1

    @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... ");
        }

    }

您需要实现过滤器,并需要使用@WebFilter(urlPatterns =“ / *”)进行注释

并且在Application或Configuration类中,您需要添加@ServletComponentScan,通过它您的过滤器将被注册。


@WebFilter仅是从Servlet 3.0开始。因此它可能无法正常工作2.5
ha9u63ar,

1

步骤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;
    }
}

您可以参考此链接以获取完整的应用程序。


0

首先,添加@ServletComponentScan到您的SpringBootApplication类。

@ServletComponentScan
public class Application {

其次,创建一个扩展了Filter或第三方过滤器类的过滤器文件,并添加@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{

0

我看到了@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 );
    }

}

0

众所周知,Spring Boot是用最少的配置和自觉的安装程序开发WebApp或StandaloneApp的绝妙方法。

这就是我在Spring Boot应用程序中实现Web筛选器开发的方式

我的SpringBootApp规格:

Spring Boot版本:2.0.4。RELEASEJava
版本:8.0
Servlet规范:Servlet 3.0(必填和重要)

我遵循Servlet规范3.0以以下方式声明了我的Web筛选器

在此处输入图片说明 这是将筛选器定义为对基于web.xml的定义的替代的编程方式。

容器将在部署过程中处理“ @Webfilter”注释,将根据配置在其中找到其Filter类,并将其应用于URL模式javax.servlet.Servlets和javax.servlet.DispatcherTypes。

为了完全避免Web.xml并实现“可部署” WebApp,请执行以下操作:

要将Spring Boot Application部署为“传统WAR”,应用程序类应扩展SpringBootServletInitializer。

注意: SpringBootServletInitializer是参考Servlet 3.0+规范的web.xml的“程序实现”,它需要WebApplicationInitializer的实现。

因此,SpringBootApplication不需要“ web.xml”作为其应用程序类(在扩展SpringBootServletInitializer之后)扫描 -@ WebFilter

-@WebListener和
- @ WebServlet 。

注释@ServletComponentScan

通过此注释,可以扫描基本程序包中带有@ WebFilter,@ WebListener和@WebServlet注释的Web组件。

由于嵌入式容器不支持@ WebServlet,@ WebFilter和@WebListener注释,Spring Boot在很大程度上依赖于嵌入式容器,因此引入了新的注释@ServletComponentScan以支持一些使用这3个注释的从属jar。

仅在使用嵌入式Servlet容器时执行扫描。

以下是我的Spring Boot应用程序类定义:

在此处输入图片说明

自定义Servlet初始化程序:

在这里:我定义了一个自定义类:“ ServletInitializer”,它扩展了类:SpringBootServletInitializer。

如前所述,SpringBootServletInitializer负责扫描注释: --@WebFilter

-@WebListener和
- @WebServlet 。

因此,Spring Boot Application Class应该

  • 扩展类:SpringBootServletInitializer或
  • 扩展自定义类,扩展该类:SpringBootServletInitializer

在此处输入图片说明


-6

过滤器主要用于记录器文件,它根据您在项目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>

过滤器用于限制数据,而我使用阈值过滤器进一步限制流中的数据级别,我提到了可以在那里限制的级别。有关更多信息,请参见log4j2-Log4J的级别顺序:所有>跟踪>调试>信息>警告>错误>致命>关


FilterRegistrationBean正如问题中提到的javax.servlet.Filter,这个答案是在谈论org.apache.logging.log4j.core.Filter
Steve Buzonas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.