Java 如何根据 URL 模式应用 Spring Boot 过滤器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39710526/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 21:22:36  来源:igfitidea点击:

How to apply spring boot filter based on URL pattern?

javaspringfilterspring-bootannotations

提问by user1283002

I have created a spring boot filter - implements GenericFilterBeanwith @Componentannotation.

我创建了一个 Spring Boot 过滤器 -GenericFilterBean使用@Component注释实现。

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

The filter is automatically identified by the Spring Boot Framework and works fine for all of the REST API. I want this filter to apply only on a certain URL path, such as /api/secure/*but I can't find the right way. I tried @WebFilterbut it didn't work. I'm not using XML configuration or servlet initializer - just the annotations.

过滤器由 Spring Boot 框架自动识别,适用于所有 REST API。我希望此过滤器仅适用于某个 URL 路径,例如/api/secure/*但我找不到正确的方法。我试过了,@WebFilter但没有用。我没有使用 XML 配置或 servlet 初始值设定项 - 只是注释。

What would be the correct way to get it working?

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

采纳答案by Ulises

You can add a filter like this:

您可以添加这样的过滤器:

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

回答by vegemite4me

There is another option if you are able to extend OncePerRequestFilter. For example:

如果您能够扩展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/");
    }
}

回答by artemisian

@user1283002 I think it's possible to do using @WebFilter. I just stumbled upon this article. As per the article (haven't tried myself):

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

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

}

EDIT:After further reading the docs for the @ServletComponentScanI came across an interesting disclaimer

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

Scanning is only performed when using an embedded webserver

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

Which means that when deploying our application in a web container (eg: Apache Tomcat) this class won't get scanned by the Spring framework and therefore any spring config on it (if any) won't be applied.

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

If there is no Spring config to be made you are good to go without any further changes, if not just add the @Componentscan to the filter and make sure it's package is in the path of your @ComponentScanannotation.

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