Spring Boot过滤模式匹配错误的网址

时间:2016-04-29 17:23:27

标签: spring spring-mvc filter spring-boot servlet-filters

我正在开发一个Spring Boot Web应用程序。它包含以下配置类:

@Configuration
public class FilterRegistration {

    @Bean
    public FilterRegistrationBean provideTestFilter() {
        final FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new OncePerRequestFilter() {
            @Override
            protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws ServletException, IOException {
                throw new RuntimeException("I shouldn't be thrown!");
            }
        });
        registrationBean.addUrlPatterns("/users/*");
        return registrationBean;
    }

}

我可以告诉过滤器已成功注册,因为在启动期间,控制台会记录以下条目:

o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'oncePerRequestFilter' to urls: [/users/*]

当我测试端点时,我得到以下结果:

curl localhost:8080/users/bob - > {"status": 500, "message": "I shouldn't be thrown!"}

curl localhost:8080/users/ - > {"status": 500, "message": "I shouldn't be thrown!"}

curl localhost:8080/users - > {"status": 500, "message": "I shouldn't be thrown!"}

curl localhost:8080/usersx - > {"status": 404, "error": "Not Found"}

预计会有第一个和最后一个结果,但为什么网址格式/users/*也会与网址/users//users匹配?

对于 _not _ 匹配这两个网址的Spring网址格式是否有不同的语法,并且仅匹配/users/bob/users/alice/users/any_non_empty_string

1 个答案:

答案 0 :(得分:4)

根据Servlet规范,过滤器模式的行为与其应有的完全相同。规范描述了Servlet方面的映射,但同样的规则也适用于过滤器。它提供了以下示例映射:

  • /foo/bar/*已映射到servlet1
  • /baz/*已映射到servlet2
  • /catalog已映射到servlet3
  • *.bop已映射到servlet4

鉴于这些映射,将导致以下行为:

  • /foo/bar/index.htmlservlet1
  • 处理
  • /foo/bar/index.bopservlet1
  • 处理
  • /bazservlet2
  • 处理
  • /baz/index.htmlservlet2
  • 处理
  • /catalogservlet3
  • 处理
  • /catalog/index.htmldefault servlet
  • 处理
  • /catalog/racecar.bopservlet4
  • 处理
  • /index.bopservlet4
  • 处理

您所描述的案例与/baz处理servlet2的请求相同,该请求已映射到/baz/*

  

对于 匹配这两个网址的Spring网址格式是否有不同的语法,只匹配/ users / bob,/ users / alice或/ users / any_non_empty_string?

如上例所示,Servlet规范并未提供对此类映射的支持。您需要添加一些逻辑来处理该情况。您可以直接在过滤器中执行此操作,也可以在另一个首先运行的过滤器中执行此操作,并设置请求属性,告知其他过滤器忽略该请求。