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

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

Spring Boot参考指南中提到过 FilterRegistrationBean,但我不确定如何使用它。


当前回答

添加过滤器有三种方法,

用一个Spring原型(如@Component)注释你的过滤器 在Spring @Configuration中注册一个Filter类型的@Bean 在Spring @Configuration中用FilterRegistrationBean类型注册一个@Bean

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.

虽然结合#2和#3效果很好,但我很惊讶它最终没有应用两次两个过滤器。我的猜测是,当Spring调用相同的方法来创建这两个bean时,它将这两个bean合并为一个。如果您想单独使用#3和authwiring,您可以使用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;
    }

其他回答

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

@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

    }

}

添加过滤器有三种方法,

用一个Spring原型(如@Component)注释你的过滤器 在Spring @Configuration中注册一个Filter类型的@Bean 在Spring @Configuration中用FilterRegistrationBean类型注册一个@Bean

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.

虽然结合#2和#3效果很好,但我很惊讶它最终没有应用两次两个过滤器。我的猜测是,当Spring调用相同的方法来创建这两个bean时,它将这两个bean合并为一个。如果您想单独使用#3和authwiring,您可以使用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;
    }

首先,将@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{

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

}

过滤器主要用于日志文件中。它根据您在项目中使用的记录器而有所不同。

让我解释一下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