Java 如何在Spring Boot中添加筛选器类?

Java 如何在Spring Boot中添加筛选器类?,java,configuration,spring-boot,servlet-filters,Java,Configuration,Spring Boot,Servlet Filters,Spring Boot中是否有过滤器类(用于web应用程序)的注释?也许是@过滤器 我想在我的项目中添加自定义筛选器 提到 FilterRegistrationBean,但我不知道如何使用它。没有表示servlet过滤器的特殊注释。您只需声明一个类型为Filter(或FilterRegistrationBean)的@Bean。一个例子(为所有响应添加一个自定义头)在Boot自己的版本中 如果只声明一个过滤器,它将应用于所有请求。如果您还添加了一个FilterRegistrationBean,那么

Spring Boot中是否有
过滤器
类(用于web应用程序)的注释?也许是
@过滤器

我想在我的项目中添加自定义筛选器

提到
FilterRegistrationBean
,但我不知道如何使用它。

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


如果只声明一个
过滤器
,它将应用于所有请求。如果您还添加了一个
FilterRegistrationBean
,那么您可以另外指定要应用的单个servlet和url模式

注意:


从Spring Boot 1.4开始,
FilterRegistrationBean
并没有被弃用,只是简单地将包从
org.springframework.Boot.context.embedded.FilterRegistrationBean
移动到
org.springframework.Boot.web.servlet.FilterRegistrationBean
没有特别的注释来表示servlet过滤器。您只需声明一个类型为
Filter
(或
FilterRegistrationBean
)的
@Bean
。一个例子(为所有响应添加一个自定义头)在Boot自己的版本中


如果只声明一个
过滤器
,它将应用于所有请求。如果您还添加了一个
FilterRegistrationBean
,那么您可以另外指定要应用的单个servlet和url模式

注意:


从弹簧护套1.4开始,
FilterRegistrationBean
没有被弃用,只是将包从
org.springframework.boot.context.embedded.FilterRegistrationBean
移动到
org.springframework.boot.web.servlet.FilterRegistrationBean

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

}

下面是一个在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 {}

}

如果要设置第三方筛选器,可以使用
FilterRegistrationBean

例如,web.xml的等价物:


某些过滤器
com.somecompany.SomeFilter
某些过滤器
/网址/*
参数名
参数值
这些将是
@配置文件中的两个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测试的。

如果要设置第三方筛选器,可以使用
FilterRegistrationBean

例如,web.xml的等价物:


某些过滤器
com.somecompany.SomeFilter
某些过滤器
/网址/*
参数名
参数值
这些将是
@配置文件中的两个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原型之一(如
    @Component
  • 在Spring
    @Configuration
    中使用
    Filter
    类型注册
    @Bean

  • 使用Spring中的
    过滤器注册Bean
    类型注册
    @Bean
  • 如果您希望筛选器应用于所有请求而不进行自定义,则可以使用#1或#2,否则请使用#3。只要将过滤器类放在
    SpringApplication
    类的相同或子包中,就不需要为#1指定组件扫描。对于#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;
        }
    

    有三种方法可以添加过滤器

  • 使用Spring原型之一(如
    @Component
  • 在Spring
    @Configuration
    中使用
    Filter
    类型注册
    @Bean

  • 使用Spring中的
    过滤器注册Bean
    类型注册
    @Bean
  • 如果您希望筛选器应用于所有请求而不进行自定义,则可以使用#1或#2,否则请使用#3。只要将过滤器类放在
    SpringApplication
    类的相同或子包中,就不需要为#1指定组件扫描。对于#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;
        }
    

    从Spring文档中

    要添加Servlet、筛选器或Servlet*侦听器,请提供@Bean 它的定义

    例如:

    @Bean
    public Filter compressFilter() {
        CompressingFilter compressFilter = new CompressingFilter();
        return compressFilter;
    }
    
    将此
    @Bean
    配置添加到
    @configuration
    类中,过滤器将在启动时注册

    还可以使用类路径扫描添加servlet、筛选器和侦听器

    @WebServlet、@WebFilter和@WebListener注释类可以是 自动向嵌入式服务器注册
    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(urlPatterns = "/*")
    public class MyFilter implements Filter {
    }
    
    @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
    
        }
    
    }
    
    <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>
    
    @Component
    public class ExampleFilter implements Filter {
        ...
    }
    
    @WebFilter(urlPatterns = "/api/count")
    public class ExampleFilter implements Filter {
        ...
    }
    
    @ServletComponentScan
    @SpringBootApplication
    public class MyApplication extends SpringBootServletInitializer {
        ...
    }
    
        <?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>
    
    @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();
        }
    }
    
    @ServletComponentScan
    public class Application {
    
    @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{
    
    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() {
    
        }
    }
    
    @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");
        }
    
    }
    
    @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 );
        }
    
    }
    
    @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(1)
     public class CustomFirstFilter implements Filter {
    
     }
    
     @Component
     @Order(2)
     public class CustomSecondFilter implements Filter {
    
     }
    
    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() {
    
        }
    }
    
    @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;
        }
    }
    
    @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
    
        }
    
    }
    
    @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);
        }
    }
    
    @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);
        }
    }
    
    @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(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);
        }
    }
    
      @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() {
          }
      }
    
    @Component
    public class PerformanceFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
    
            ...
            ...
        }
    
    }
    
    @Configuration
    public class FilterConfig {
        @Bean
        public FilterRegistrationBean<PerformanceFilter> perfFilter() {
            FilterRegistrationBean<PerformanceFilter> registration = new FilterRegistrationBean<>();
            registration.setFilter(new PerformanceFilter());
            registration.addUrlPatterns("/*");
            return registration;
        }
    }