Spring Boot - Filters and Interceptors

Let’s learn about Filters and Interceptors

Filter

A filter must implement javax.servlet.Filter Interface

A filter is an object that performs filtering tasks on either the request to a resource (a servlet or static content), or on the response from a resource, or both.

Filters are great for login authentication and work on ServletRequest and ServletResponse. Interceptors works on the method execution.

Filter interface contains three methods

  • init(FilterConfig filterConfig)
  • doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  • destroy()

The FilterChain passed in to doFilter method allows the Filter to pass on the request and response to the next entity in the chain.

You can set the filter order using @Order annotation

Filter Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Component
@Order(1)
public class RequestResponseLoggingFilter implements Filter {
private static final Logger LOG = LoggerFactory.getLogger(RequestResponseLoggingFilter.class);

@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;

LOG.info("Logging Request {} : {}", req.getMethod(), req.getRequestURI());

chain.doFilter(request, response);

LOG.info("Logging Response :{}", res.getContentType());
}

@Override
public void destroy() {
// TODO Auto-generated method stub
}
}

Interceptor

All interceptors implement HandlerInterceptor interface.

HandlerInterceptor can be registered for only certain request paths. use /** for all URL path.

HandlerInterceptor contains three methods:

  • preHandle() : called before a request is handled. The default returns true to proceed the request.
  • postHandle() : called after request is handled. It also has access to ModelAndView object.
  • afterCompletion() : after all processing is completed. e.g. view is render

Spring provides HandlerInterceptorAdapter abstract class that provides simplified implementation of
pre-only/post-only interceptors.

ProcessTimeInterceptor logs the process time for the incoming request

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Component
public class ProcessTimeInterceptor extends HandlerInterceptorAdapter{
private static final Logger LOG = LoggerFactory.getLogger(ProcessTimeInterceptor.class);

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
long startTime = System.currentTimeMillis();
request.setAttribute("startTime", startTime);
return true;
}

/**
* sample log output: Request Processing Time: 4ms for path /
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
long startTime = (Long) request.getAttribute("startTime");
request.removeAttribute("startTime");

long endTime = System.currentTimeMillis();

String path = null;
if(StringUtils.isEmpty(request.getQueryString())) {
path = request.getServletPath();
}else {
path = request.getServletPath() + "?" + request.getQueryString();
}
LOG.info("Request Processing Time: " + (endTime - startTime) + "ms for path "
+ path);
}
}

Then add the interceptor to the interceptors list.

1
2
3
4
5
6
7
8
9
10
11
@Configuration
public class WebConfiguration implements WebMvcConfigurer{

@Autowired
private ProcessTimeInterceptor processTimeInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(processTimeInterceptor).addPathPatterns("/**");
}
}

Sample output for the above Filter and Interceptor

1
2
3
2019-05-06 23:25:40.862  INFO 5722 --- [nio-8080-exec-8] c.e.demo.RequestResponseLoggingFilter    : Logging Request  GET : /hello
2019-05-06 23:25:40.865 INFO 5722 --- [nio-8080-exec-8] com.example.demo.ProcessTimeInterceptor : Request Processing Time: 2ms for path /hello
2019-05-06 23:25:40.865 INFO 5722 --- [nio-8080-exec-8] c.e.demo.RequestResponseLoggingFilter : Logging Response :text/html;charset=UTF-8

Reference

source code - SpringBootExamples - filter-and-interceptor