如何为包含特定单词的网址启用过滤器?

时间:2019-07-30 04:36:04

标签: java spring-boot filter

我正在尝试使用过滤器将请求记录到某些URL。

我想要的某些URL是包含单词api的URL,所以从"/aaaa/api""/api/items/3"的所有URL。

在我被告知更改它以使其与其中任何带有"api"的URL匹配之前,我已经在Filter Config中设置了URL模式,但是我删除了它,并使用regex来过滤{{1 }},如下所示。

我的问题是:是否有一种方法可以通过在Filter Config中编辑ApiLogFilter的模式来实现?还有,最佳做法是什么?

addUrlPatterns
@Configuration
public class FilterConfig {

@Bean
public FilterRegistrationBean<ApiLogFilter> 
filterRegistrationBean() {
    FilterRegistrationBean<ApiLogFilter> registrationBean = new 
FilterRegistrationBean();
    registrationBean.setFilter(new ApiLogFilter());
    registrationBean.addUrlPatterns("/api/items/*");
    return registrationBean;
}

1 个答案:

答案 0 :(得分:1)

在Spring中,您有两个用于处理HTTP请求/响应的选项。这些使用的是 servlet过滤器(如您所做的那样)或拦截器link)。

过滤器可以更改请求/响应,甚至可以完全停止HTTP工作流。如果过滤器中有未处理的异常,则您的请求将停止工作。

拦截器无法更改请求/响应。它可以听。与筛选器不同,如果您在拦截器请求中遇到了无法理解的异常,则该请求不会停止工作(您只能在控制台或日志中获取消息)。

关于URL模式:它具有非常简单的语法。实际上,您几乎所能做的就是在字符串的开头或结尾指定星号。 *.ext-表示扩展名为ext的文件。 /api/*-表示所有内容均以/api/开头。我想这种简单性是为了提高性能。但这不符合您的要求。

在过滤器中使用regexp没有错。它不会显着影响性能。一切都OK,除了一句话。正则表达式处理包括两部分:regexp的编译和匹配字符串。每次调用getRequestURI().matches()时,都会同时执行这两个部分。最好只编译一次regexp。添加到您的过滤器:

private static Pattern pattern = Pattern.compile(".*/api/.*");

然后您可以在过滤器的方法中使用预编译的模式:

@Override
public final void doFilterInternal(
    HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
    ...
    if (pattern.matcher(request.getRequestURI()).matches()) {
        //process query
    }   
}

这种方法可以避免每次使用时都重新编译模式。