Spring HandlerInterceptor Example

As you know about servlet filters that they can pre-handle and post-handle every web request they serve – before and after it’s handled by that servlet. In the similar way, you can use HandlerInterceptor interface in your spring web application to pre-handle and post-handle web requests that are handled by Spring MVC handlers. These handlers are mostly used to manipulate the model attributes returned/submitted they are passed to the views/handlers.

HandlerInterceptor Interface

Handler interceptors are configured in Spring’s web application context, so they can make use of any container features and refer to any beans declared in the container. A handler interceptor can be registered for particular URL mappings, so it only intercepts requests mapped to certain URLs.

Each handler interceptor must implement the HandlerInterceptor interface, which contains three callback methods for you to implement: preHandle(), postHandle(), and afterCompletion().

  • preHandle() : Before a request is handled by a request handler.
  • postHandle() : After a request is handled by a request handler. It gives access to the returned ModelAndView object, so you can manipulate the model attributes in it.
  • afterCompletion() : After the completion of all request processing i.e. after the view has been rendered.

HandlerInterceptorAdapter Class

Problem with HandlerInterceptor interface is that your new class will have to implement all three methods irrespective of whether it is needed or not. To avoid overriding, you can use HandlerInterceptorAdapter class. This class implements HandlerInterceptor and provide default blank implementations.

So whatever methods you want to override in your handler, you can extend it from HandlerInterceptorAdapter.

HandlerInterceptor Interface Example

I am reusing the code created for Spring MVC hello world application here. I am creating a CustomRequestHandler class. Methods of this class (i.e. preHandle(), postHandle() and afterCompletion()) will be called as per above discussion.

package com.howtodoinjava.demo.handlers;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class CustomRequestHandler extends HandlerInterceptorAdapter 
{

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

	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();
        modelAndView.addObject("totalTime", endTime - startTime);
        
        System.out.println("Request Prcessing Time :: " + (endTime - startTime));
	}

	public void afterCompletion( HttpServletRequest request,
									HttpServletResponse response, 
									Object handler, 
									Exception exceptionIfAny) 
					throws Exception 
	{
		System.out.println("View Rendered !!");
	}
}

Now when you have created your request handler, it must be declared into spring configuration file so that spring can pass requests to it at appropriate time.

A handler interceptor is registered to the DefaultAnnotationHandlerMapping bean, which is charged with applying interceptors to any class marked with a @Controller annotation. You can specify multiple interceptors in the interceptors property, whose type is an array.

<bean id="customRequestHandler" class="com.howtodoinjava.demo.handlers.CustomRequestHandler" />

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
	
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
	<property name="interceptors">
		<list>
			<ref bean="customRequestHandler" />
		</list>
	</property>
</bean>

Now when you run the hello world application again, it will print below output.

Request Precessing Time :: 15
View Rendered !!

Applying HandlerInterceptor Interface to certain URLs only

Well, using above approach you handler will be applied on all controllers in your application irrespective of what URLs they are mapped to. If you want to map your handler to certain URL only then you will have to use <mvc:interceptors>> tag.

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/somepath_one/*"/>
        <ref bean="customRequestHandler_one" />
    </mvc:interceptor>
	<mvc:interceptor>
        <mvc:mapping path="/somepath_two/*"/>
        <ref bean="customRequestHandler_two" />
    </mvc:interceptor>
</mvc:interceptors>

That’s all for this quick tip.

Happy Learning !!

Comments

Subscribe
Notify of
guest
2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode