Main Tutorials

Spring MVC handler interceptors example

Spring MVC allow you to intercept web request through handler interceptors. The handler interceptor have to implement the HandlerInterceptor interface, which contains three methods :

  1. preHandle() – Called before the handler execution, returns a boolean value, “true” : continue the handler execution chain; “false”, stop the execution chain and return it.
  2. postHandle() – Called after the handler execution, allow manipulate the ModelAndView object before render it to view page.
  3. afterCompletion() – Called after the complete request has finished. Seldom use, cant find any use case.

In this tutorial, you will create two handler interceptors to show the use of the HandlerInterceptor.

  1. ExecuteTimeInterceptor – Intercept the web request, and log the controller execution time.
  2. MaintenanceInterceptor – Intercept the web request, check if the current time is in between the maintenance time, if yes then redirect it to maintenance page.
Note
It’s recommended to extend the HandlerInterceptorAdapter for the convenient default implementations.

1. ExecuteTimeInterceptor

Intercept the before and after controller execution, log the start and end of the execution time, save it into the existing intercepted controller’s modelAndView for later display.

File : ExecuteTimeInterceptor.java


package com.mkyong.common.interceptor;

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

import org.apache.log4j.Logger;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class ExecuteTimeInterceptor extends HandlerInterceptorAdapter{
	
	private static final Logger logger = Logger.getLogger(ExecuteTimeInterceptor.class);

	//before the actual handler will be executed
	public boolean preHandle(HttpServletRequest request, 
		HttpServletResponse response, Object handler)
	    throws Exception {
		
		long startTime = System.currentTimeMillis();
		request.setAttribute("startTime", startTime);
		
		return true;
	}

	//after the handler is executed
	public void postHandle(
		HttpServletRequest request, HttpServletResponse response, 
		Object handler, ModelAndView modelAndView)
		throws Exception {
		
		long startTime = (Long)request.getAttribute("startTime");
		
		long endTime = System.currentTimeMillis();

		long executeTime = endTime - startTime;
		
		//modified the exisitng modelAndView
		modelAndView.addObject("executeTime",executeTime);
		
		//log it
		if(logger.isDebugEnabled()){
		   logger.debug("[" + handler + "] executeTime : " + executeTime + "ms");
		}
	}
}

2. MaintenanceInterceptor

Intercept before the controller execution, check if the current time is in between the maintenance time, if yes then redirect it to maintenance page; else continue the execution chain.

File : MaintenanceInterceptor.java


package com.mkyong.common.interceptor;

import java.util.Calendar;

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

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

public class MaintenanceInterceptor extends HandlerInterceptorAdapter{
	
	private int maintenanceStartTime;
	private int maintenanceEndTime;
	private String maintenanceMapping;
	
	public void setMaintenanceMapping(String maintenanceMapping) {
		this.maintenanceMapping = maintenanceMapping;
	}

	public void setMaintenanceStartTime(int maintenanceStartTime) {
		this.maintenanceStartTime = maintenanceStartTime;
	}

	public void setMaintenanceEndTime(int maintenanceEndTime) {
		this.maintenanceEndTime = maintenanceEndTime;
	}

	//before the actual handler will be executed
	public boolean preHandle(HttpServletRequest request, 
			HttpServletResponse response, Object handler)
	    throws Exception {
		
		Calendar cal = Calendar.getInstance();
		int hour = cal.get(cal.HOUR_OF_DAY);
		
		if (hour >= maintenanceStartTime && hour <= maintenanceEndTime) {
			//maintenance time, send to maintenance page
			response.sendRedirect(maintenanceMapping);
			return false;
		} else {
			return true;
		}
		
	}
}

3. Enable the handler interceptor

To enable it, put your handler interceptor class in the handler mapping “interceptors” property.


<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/welcome.htm">welcomeController</prop>
			</props>
		</property>
		<property name="interceptors">
			<list>
				<ref bean="maintenanceInterceptor" />
				<ref bean="executeTimeInterceptor" />
			</list>
		</property>
	</bean>

	<bean
	class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
		<property name="interceptors">
			<list>
				<ref bean="executeTimeInterceptor" />
			</list>
		</property>
	</bean>

	<bean id="welcomeController" 
                  class="com.mkyong.common.controller.WelcomeController" />
	<bean class="com.mkyong.common.controller.MaintenanceController" />

	<bean id="executeTimeInterceptor" 
                 class="com.mkyong.common.interceptor.ExecuteTimeInterceptor" />

	<bean id="maintenanceInterceptor" 
                class="com.mkyong.common.interceptor.MaintenanceInterceptor">
		<property name="maintenanceStartTime" value="23" />
		<property name="maintenanceEndTime" value="24" />
		<property name="maintenanceMapping" value="/SpringMVC/maintenance.htm" />
	</bean>

	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix">
			<value>/WEB-INF/pages/</value>
		</property>
		<property name="suffix">
			<value>.jsp</value>
		</property>
	</bean>

</beans>

Download Source Code

References

  1. HandlerInterceptorAdapter documentation
  2. HandlerInterceptor documentation
  3. ControllerClassNameHandlerMapping example
  4. SimpleUrlHandlerMapping example

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
20 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Keyur Bhatt
8 years ago

Hi, will you tell me that how to do java class based configuration of Interceptor instead of XML based ? I am facing issue of it. My whole application is class based configuration. I am using Spring boot.

Saba
6 years ago

on my case request.setAttribute(params, value); not working Interceptor preHandle method, used Filter and HttpServletRequestWrapper class, which allows you to wrap one request with another, and override the getParameter method to return my sanitized value.spring mvc

raghu A
7 years ago

how to exclude some urls in Interceptor ()

Jay Khimani
8 years ago

Dont know how many times your site has helped me found exactly what I’m looking for. Thanks once again.

SRIRAM
8 years ago

how to model objet value in my prehandle class please help mme below is code.

Welcome

User Name:

Password:

package com.cea.controller;

import java.text.DateFormat;

import java.util.Date;

import java.util.Locale;

import java.util.ResourceBundle;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import com.cea.model.LoginUser;

@Controller

public class LoginController {

private static final Logger logger = LoggerFactory

.getLogger(LoginController.class);

static String bundle = “configuration”;

public static ResourceBundle settings = ResourceBundle.getBundle(bundle);

@RequestMapping(value = “/login”, method = RequestMethod.GET)

public String getMinutes(@ModelAttribute(“loginuser”) LoginUser loginuser) {

return “login”;

}

@RequestMapping(value = “/login”, method = RequestMethod.POST)

public String login(Model model, LoginUser loginuser, Locale locale,

HttpServletRequest request) throws Exception {

Date date = new Date();

DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,

DateFormat.LONG, locale);

String formattedDate = dateFormat.format(date);

String username = loginuser.getUserName();

String password = loginuser.getPassword();

logger.info(“Login attempt for username ” + username + ” at: ”

+ formattedDate);

// A simple authentication manager

if (username != null && password != null) {

if (username.equals(settings.getString(“username”))

&& password.equals(settings.getObject(“password”))) {

// Set a session attribute to check authentication then redirect

// to the welcome uri;

request.getSession().setAttribute(“LOGGEDIN_USER”, loginuser);

return “redirect:/login”;

} else {

return “redirect:/login”;

}

} else {

return “redirect:/login”;

}

}

}

package com.cea.interceprotutilities;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

import com.cea.controller.LoginController;

import com.cea.model.LoginUser;

public class LoginInterceptor implements HandlerInterceptor {

private static final Logger logger = LoggerFactory

.getLogger(LoginInterceptor.class);

public boolean preHandle(HttpServletRequest request,

HttpServletResponse response, Object handler) throws Exception {

System.out.println(“GreetingInterceptor: REQUEST Intercepted for URI: ”

+ request.getRequestURI());

request.setAttribute(“greeting”, “Happy Diwali!”);

request.setAttribute(“RAMA”, “JAISRIRAM”);

LoginUser loginuser=(LoginUser)request.getSession().getAttribute(“LOGGEDIN_USER”);

if(loginuser==null && request.getRequestURI().equals(“/cea2/login”))

{

request.setAttribute(“RAMA”, “SESSION FAILED”);

String userName = (String)request.getAttribute(“userName”);

if(userName!=null)

logger.info(“Login attempt for username ” + userName );

}

return true;

}

public void postHandle(HttpServletRequest request,

HttpServletResponse response, Object handler,

ModelAndView modelAndView) throws Exception {

// TODO Auto-generated method stub

}

public void afterCompletion(HttpServletRequest request,

HttpServletResponse response, Object handler, Exception ex)

throws Exception {

// TODO Auto-generated method stub

}

}

Arvind
9 years ago

We can also configure HandlerInterceptor using java configuration as

@Configuration

public class AppConfig extends WebMvcConfigurerAdapter {

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new LoggingInterceptor());

registry.addInterceptor(new TransactionInterceptor()).addPathPatterns(“/person/save/*”);

}

}

Find the detail.

http://www.concretepage.com/spring/spring-mvc/spring-handlerinterceptor-annotation-example-webmvcconfigureradapter

Eric Butler
9 years ago

The before and after handling was illustrated really simply with that timer interceptor. Thanks.

Sanjay Jain
9 years ago

I have written a test interceptor and path is configured as “/**” which is working fine for all the url except context root path. My context root is referring to wel come file under WEB-INF folder. So how should I set path so that my interceptor get invoked for all urls including context root path ? Spring version 3.2.8

Majid
10 years ago

Hi,
I just downloaded the source code , imported it in eclipse, can you please tell me how to run it , should I call one of the jsp files or what ?
thanks

Majid
10 years ago
Reply to  Majid

I called :
http://localhost:8080/SpringMVC/WelcomePage.htm

but I got :
HTTP Status 404 –

WARN PageNotFound:1077 – No mapping found for HTTP request with URI [/SpringMVC/WelcomePage.htm] in DispatcherServlet with name ‘mvc-dispatcher’

Thanks, your help is appreciated.

Don Good
10 years ago

Once again you have posted exactly what I was looking for! Great job!

Mohan
11 years ago

To the point for a quick reference

vijayaraj
11 years ago

Its good example..

RAJA
11 years ago
Reply to  vijayaraj

Good example

Yashwant Chavan
11 years ago

Great tutorial mkyong
Thanks

Somabrata
11 years ago

I want to configure my Interceptor for all the urls, My xml configuration is like this:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
           
	<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
    
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                  <prop key="/mylink1.html">mylink1</prop>
                  <prop key="/mylink2.html">mylink2</prop>
             </props>
        </property>
       
        <property name="interceptors">
			<list>
				<ref bean="myInterceptor" />
			</list>
	</property>
    </bean>
    <bean id="myInterceptor" class="correct.class.path.MyInterceptor">
    </bean>
    <bean name="mylink1"
          class="org.springframework.web.servlet.mvc.ParameterizableViewController">
        <property name="viewName" value="MyLink1" />   
    </bean>
    <bean name="mylink2"
          class="org.springframework.web.servlet.mvc.ParameterizableViewController">
        <property name="viewName" value="MyLink2" />   
    </bean>
    <bean class="package.MyController">
        <property name="formView" value="MyApp" />
    </bean>   
</beans>

For mylink1.html and mylink2.html MyInterceptor is being fired,
For myapp.html MyController is fired but not the MyInterceptor,
I tried with,

<property name="mappings">
            <props>
                  <prop key="/mylink1.html">mylink1</prop>
                  <prop key="/mylink2.html">mylink2</prop>
                  <prop key="/myapp.html">myApp</prop>
             </props>
</property>  

and

    <bean name="myApp" class="package.MyController">
        <property name="formView" value="MyApp" />
    </bean> 

Then also interceptor is not being fired.
I know how to do it with spring-beans-3.0.xsd and spring-mvc-3.0.xsd but i have to stay with 2.5 version

Vikas
12 years ago

I want to use interceptor as SignInInterceptor (or say Filter). I have defined same by extending HandlerInterceptorAdapter.

Note that I’m using tiles2.TilesViewResolver and using Annotation for Controllers.

<bean id="viewResolver" class="org.springframework.web.servlet.view.tiles2.TilesViewResolver" >
	<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
</bean>

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
	<property name="definitions">
		<list>
			<value>/WEB-INF/tiles.xml</value>
	    </list>
	</property>
</bean>

<bean id="authenticationInterceptor" class="com.abc.AuthenticationInterceptor" />

Now, I’m not having clue regarding how to configure and use this interceptor?

Gagan
12 years ago
Reply to  Vikas
 
<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.abc.AuthenticationInterceptor"/>
        </mvc:interceptor> 
<mvc:interceptors>

Please try above configuration . This should help.

Sylar
12 years ago

Great tutorial on HI, mkyong.. Keep up the good work..please provide EJB tutorials too.. Would be helpful..

Sumit Bhowmick
12 years ago

Great. It’s a nice Spring interceptor tutorial.