如何仅将Filter过滤到一个@RequestMapping方法?

时间:2016-02-04 10:31:52

标签: spring spring-boot

我为一般内容记录注册了以下过滤器:

@Bean
public Filter getLoggingFilter() {
    CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
    filter.setIncludeQueryString(true);
    filter.setIncludePayload(true);
    filter.setMaxPayloadLength(5120);
    return filter;
}

此过滤器可捕获任何请求。

现在,我想将此过滤器仅应用于一种特定的@RequestMapping方法。

问题:这有可能吗?

更新:访问路径时,以下filterbean会产生404。

@Bean
public FilterRegistrationBean getLoggingFilter() {
    FilterRegistrationBean filter = new FilterRegistrationBean(new CommonsRequestLoggingFilter());
    filter.addUrlPatterns("/rest/my/specific/method/*");
    return filter;
}

2 个答案:

答案 0 :(得分:9)

您需要FilterRegistrationBean来指定网址映射。 the reference guide中也提到了这一事实。

@Bean
public Filter loggingFilter() {
    CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
    filter.setIncludeQueryString(true);
    filter.setIncludePayload(true);
    filter.setMaxPayloadLength(5120);
    return filter;
}

在过滤器定义旁边添加FilterRegistrationBean

@Bean
public FilterRegistrationBean loggingFilterRegistration() {
    FilterRegistrationBean registration = new FilterRegistrationBean(loggingFilter());
    registration.addUrlPatterns("/rest/my/specific/method/*");
    return registration;
}

这会将过滤器附加到指定的URL。另请注意,UrlPatterns是根URL中的模式。因此,如果您的应用程序映射到/rest,则无法调用此过滤器。

答案 1 :(得分:1)

我最近遇到了同样的情况,与@ M.Deinum答案相比,我采取了不同的方法。 org.springframework.web.filter.CommonsRequestLoggingFilter 过滤器是 org.springframework.web.filter.OncePerRequestFilter 的派生类,它提供了一项功能,可以 exclude/include 通过任何端点方法 OncePerRequestFilter#shouldNotFilter 。此方法的默认返回值决定是否必须过滤URL,因为默认返回值为 false ,此过滤器会捕获 any request < / strong>。幸运的是,我们可以通过扩展 CommonsRequestLoggingFilter 类并覆盖 shouldNotFilter 方法来自定义此行为。当每个@RequestMapping批注都映射到一个端点时,我们可以添加一些自定义逻辑来确定是否必须将请求的URL设为chained CommonsRequestLoggingFilter

创建自定义类并扩展 CommonsRequestLoggingFilter 并覆盖方法 shouldNotFilter

import org.springframework.web.filter.CommonsRequestLoggingFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Pattern;

public class CustomCommonsRequestLoggingFilter extends CommonsRequestLoggingFilter {

    private static final Pattern ONLY_LOGGING_PATTERN = Pattern.compile("/required-url");

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
//It can be either RequestURI(includes context path) 
        String loggingPattern = request.getRequestURI();
//or ServletPath based on your requirement
        //loggingPattern = request.getServletPath();

        // If you want to log a particular endpoint then return true
        // or if you don't want to log the endpoint then return false
        return ONLY_LOGGING_PATTERN.matcher(loggingPattern).find() ? true : false;
    }
}

并按如下所示注入 CommonsRequestLoggingFilter bean

@Bean
public CommonsRequestLoggingFilter loggingFilter() {
    CustomCommonsRequestLoggingFilter filter = new CustomCommonsRequestLoggingFilter();
    filter.setIncludeQueryString(true);
    filter.setIncludePayload(true);
    filter.setMaxPayloadLength(5120);
    return filter;
}