How to register a Filter to one @RequestMapping method only?

You need a FilterRegistrationBean to specify URLs mappings. This fact is also mentioned in the reference guide.

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

Next to the filter definition add the FilterRegistrationBean.

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

This will attach the filter to the specified URL. Also be aware that the UrlPatterns are patterns inside the root URL. So if your application is mapped on /rest this filter won't be invoked.


I have got into the same situation recently and I had taken different approach compared with @M.Deinum answer. org.springframework.web.filter.CommonsRequestLoggingFilter filter is the derived class of org.springframework.web.filter.OncePerRequestFilter which provides a feature to exclude/include any endpoints through the method OncePerRequestFilter#shouldNotFilter. The default return value of this method decides whether the URL has to be filtered or not, as a default return value is false, this filter catches on any request. Luckily, we can customize this behavior by extending the CommonsRequestLoggingFilter class and overriding shouldNotFilter method. As each @RequestMapping annotation is mapped to a endpoint, we can add some custom logic to decide whether the requested URL has to be chained to CommonsRequestLoggingFilter or not.

Create a custom class and extend CommonsRequestLoggingFilter and override method 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;
    }
}

and inject CommonsRequestLoggingFilter bean as below

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