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 { } @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 () { } }
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 ; } @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