如何根据URL模式应用spring boot过滤器?

use*_*002 16 java spring annotations filter spring-boot

我创建了一个spring boot过滤器 - GenericFilterBean带有@Component注释的实现.

@Component 
public class MyAuthenticationFilter  extends GenericFilterBean {
...
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
...
}
}
Run Code Online (Sandbox Code Playgroud)

该过滤器由Spring Boot Framework自动识别,适用于所有REST API.我希望此过滤器仅应用于某个URL路径,例如/api/secure/*但我找不到正确的方法.我试过@WebFilter但它没用.我没有使用XML配置或servlet初始化程序 - 只是注释.

让它运作的正确方法是什么?

Uli*_*ses 25

您可以添加如下过滤器:

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

@Bean(name = "someFilter")
public Filter someFilter() {
    return new SomeFilter();
}
Run Code Online (Sandbox Code Playgroud)

  • 我仍然很奇怪为什么它不能通过像@WebFilter这样的注释来解决,但这对我来说非常有效.谢谢! (4认同)
  • 是否可以通过注释来做到这一点? (2认同)

veg*_*4me 15

如果您能够扩展,则还有另一种选择OncePerRequestFilter。例如:

public class SomeFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // your filter logic ....
    }

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        String path = request.getServletPath();
        return !path.startsWith("/api/secure/");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这正是我所寻找的。泰 (2认同)

art*_*ian 6

@user1283002 我认为可以使用@WebFilter。我偶然发现了这篇文章。根据文章(我自己没试过):

@WebFilter(urlPatterns = "/api/count")
public class ExampleFilter implements Filter{
    // ..........
}

// and let Spring know to scan to find such @WebFilter annotation in your config
// class by using the @ServletComponentScan annotation like

@ServletComponentScan
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(MyApplication.class, args);
    }

   // ..........

}
Run Code Online (Sandbox Code Playgroud)

编辑: 在进一步阅读@ServletComponentScan的文档后,我发现了一个有趣的免责声明

仅在使用嵌入式网络服务器时执行扫描

这意味着当在 Web 容器(例如:Apache Tomcat)中部署我们的应用程序时,Spring 框架不会扫描此类,因此不会应用其上的任何 Spring 配置(如果有)。

如果没有要进行的 Spring 配置,则无需进行任何进一步更改就可以了,如果不只是将@Component扫描添加到过滤器并确保它的包位于@ComponentScan注释的路径中。