我正在尝试使用过滤器将请求记录到某些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;
}
答案 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
}
}
这种方法可以避免每次使用时都重新编译模式。