I registered the following filter for general content logging:
@Bean
public Filter getLoggingFilter() {
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
filter.setIncludeQueryString(true);
filter.setIncludePayload(true);
filter.setMaxPayloadLength(5120);
return filter;
}
This filter catches on any request.
Now I'd like to apply this filter to only one specific @RequestMapping method.
Question: is that possible at all?
Update: the following filterbean results in a 404 when accessing the path.
@Bean
public FilterRegistrationBean getLoggingFilter() {
FilterRegistrationBean filter = new FilterRegistrationBean(new CommonsRequestLoggingFilter());
filter.addUrlPatterns("/rest/my/specific/method/*");
return filter;
}
There are three ways to add your filter, Annotate your filter with one of the Spring stereotypes such as @Component. Register a @Bean with Filter type in Spring @Configuration. Register a @Bean with FilterRegistrationBean type in Spring @Configuration.
The FilterRegistrationBean is, as the name implies, a bean used to provide configuration to register Filter instances. It can be used to provide things like URL mappings etc.
A filter is an object used to intercept the HTTP requests and responses of your application. By using filter, we can perform two operations at two instances − Before sending the request to the controller. Before sending a response to the client.
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");
//The default implementation always returns false.
@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 false
// or if you don't want to log the endpoint then return true
return ONLY_LOGGING_PATTERN.matcher(loggingPattern).find() ? false : true;
}
}
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With