Spring MVC Handler Interceptor

Spring MVC’s handler interceptor is like a good friend and will help in time of need. Spring’s handler interceptor as rightly named, intercepts a request,

Spring’s interceptor can be configured for all the requests (for any URI’s requested) or for a group of URI’s (may be for a set of modules, etc.). Just remember controller and handler are the same. If you are a beginner in Spring, to better understand interceptor, please go through the Spring 3 MVC tutorial.

In real scenario, Spring MVC handler interceptors are used for authentication, logging, to add a common message to all response. For the pages displayed we want to remove all bold tags from the response, it is possible using Spring interceptor.

Important Points about Spring Interceptor

Note: My opinion on the interceptor spring configuration is, it still follows the old XML based configuration type. It will be better if the annotation based configuration is also brought into this interceptor declaration as we are doing for the controllers.

Spring 3 MVC Interceptor Example

In this below example,

AnimalInterceptor.java

package com.javapapers.spring.mvc.interceptor;

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

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

@Component
public class AnimalInterceptor extends HandlerInterceptorAdapter {
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		System.out.println("AnimalInterceptor: REQUEST Intercepted for URI: "
				+ request.getRequestURI());
		request.setAttribute("special", "I Love Animals!");
		return true;
	}
}

GreetingInterceptor.java

package com.javapapers.spring.mvc.interceptor;

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

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

@Component
public class GreetingInterceptor extends HandlerInterceptorAdapter {
	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!");
		return true;
	}
}

spring-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<context:annotation-config />
	<context:component-scan base-package="com.javapapers.spring.mvc" />

	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/view/" />
		<property name="suffix" value=".jsp" />
		<property name="order" value="1" />
	</bean>

	<mvc:interceptors>
		<bean class="com.javapapers.spring.mvc.interceptor.GreetingInterceptor" />
		<mvc:interceptor>
			<mvc:mapping path="/AnimalList" />
			<bean class="com.javapapers.spring.mvc.interceptor.AnimalInterceptor" />
		</mvc:interceptor>
	</mvc:interceptors>


</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">

  <display-name>Spring MVC Excel Export</display-name>  
  
  <servlet>
        <servlet-name>springMVCDispatcher</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
      <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/config/spring-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMVCDispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

  
</web-app>

HelloWorldController.java

package com.javapapers.spring.mvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloWorldController {

	@RequestMapping("/")
	public String hello() {
		return "hello";
	}

	@RequestMapping(value = "/hi", method = RequestMethod.GET)
	public String hi(@RequestParam("name") String name, Model model) {
		String message = "Hi " + name + "!";
		model.addAttribute("message", message);
		return "hi";
	}

}

ZooController.java

package com.javapapers.spring.mvc.controller;

import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.javapapers.spring.mvc.Animal;
import com.javapapers.spring.mvc.AnimalService;

@Controller
public class ZooController {

	protected AnimalService animalService = new AnimalService();

	@RequestMapping(value = "/AnimalList", method = RequestMethod.GET)
	public String getAnimals(Model model) {
		List animalList = animalService.getAnimalList();
		model.addAttribute("animalList", animalList);
		return "AnimalList";
	}

}

view – JSPs


AnimalList.jsp:
<html>
<body>
<em>Welcome! <c:out value="${greeting}"></c:out> <c:out value="${special}"></c:out></em>
<hr />
<h1>Example for Spring MVC Excel Export</h1>
<h2>Animal List</h2>
...


hi.jsp:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html><head><title>Result</title></head><body>
<em>Welcome! <c:out value="${greeting}"></c:out> <c:out value="${special}"></c:out></em>
<hr />
        <h1><c:out value="${message}"></c:out></h1>        
        <h2><a href="./AnimalList">Animal List</a></h2>
    </body></html>

hello.jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html><head><title>Home</title></head><body>
<em>Welcome! <c:out value="${greeting}"></c:out> <c:out value="${special}"></c:out></em>
<hr /><h1>Hello World!</h1><hr />
<h2><a href="./AnimalList">Animal List</a></h2><hr/>
<form action="hi">Name: <input type="text" name="name"> 
<input type="submit" value="Submit"></form>
</body></html>

Other Classes

Animal.java and AnimalService.java are of not much interest to the Spring MVC interceptor topic, but required to run the example and included in the download below.

Output (only GreetingInterceptor):

Interceptor 1

Output (for page /AnimalList ) both interceptors invoked:

Intercept or 2

Server Console Log for the Interceptors:

The log statements we have added in the Spring interceptor classes will come in log as follows,

GreetingInterceptor: REQUEST Intercepted for URI: /springmvcinterceptor/
GreetingInterceptor: REQUEST Intercepted for URI: /springmvcinterceptor/AnimalList
AnimalInterceptor: REQUEST Intercepted for URI: /springmvcinterceptor/AnimalList

Download Example Project Source Code: Spring MVC Interceptor

This Spring tutorial was added on 18/10/2013.

Comments on "Spring MVC Handler Interceptor" Tutorial:

  1. sridhar says:

    Thanks.Explained in a great way.I have one question over here can u tell me the functionality difference between the filter and interceptor ?

  2. Mahesh says:

    Nice Example, Thank you

  3. Senthil Prabhu says:

    Hi Joe,

    Thanks for writing the topic I requested. It is very easier to understand now. Example is nice. Thank you lot much.

  4. Joe says:

    Filter vs Interceptor:

    1. Filter is at very high level. It is generic.
    2. Handler interceptor has got options, once intercepted it has access to the controller (handler) object on which the intercept has happened. We can do request specific operations.
    3. Interceptor can be configured based on handler mappings. We can intercept based on group of URLs and exclude URLs among them.
    4. Filter is configured in web.xml and interceptor is configured in spring context.
    5. Filter is more powerful, the request and response object that is passed on to the next level can be changed.
    6. Interceptor allows handler pre and post processing.

  5. Joe says:

    Welcome Senthil.

  6. Taher says:

    Good to understand

  7. Joe says:

    Thanks Taher.

  8. Mistake says:

    Do fix your copyright year in the footer of website. We are about to enter 2014 :)

  9. Joe says:

    Fixed it, thank you :-)

  10. Kuntal says:

    If you have a need to do something completely generic (e.g. log all requests), then a filter is sufficient – but if the behavior depends on the target handler or you want to do something between the request handling and view rendering, (e.g. intercepts all requests and reroutes the user to a specific page if the time is not between 9 a.m. and 6 p.m.) then the HandlerInterceptor provides that flexibility.

  11. Ajit Paswan says:

    Kudos Joe!
    Your examples are too good :)

  12. Joe says:

    Thanks Ajit.

  13. fl4l says:

    Great Example,
    I create my CustomInterceptor to realize a sort of input validation, then in preHandle method I have to read from HttpServletRequest.
    If input is not valid I write to HttpServletResponse and then return false.
    But if input is valid and the method returns true, I get an exception like:

    getReader() has already been called for this request

    The reason is that HttpServletRequest is readable only once.
    Is there a way to avoid this exception managing request directly in Interceptor without clone HttpServletRequest as suggested in http://stackoverflow.com/a/9260485/2186777 post ?

    Thanks a lot

  14. Ramu says:

    If PreHandle() returns false then what will happen and where control will go….?

  15. Kaleeswaran P says:

    Very nice explanation Joe..

  16. Joe says:

    Thanks Kaleeswaran.

  17. Akash says:

    Great work!

  18. Jean Pierre says:

    Hi Ramu, return false stop the request, before you can redirect the page to index:

    response.sendRedirect(“index”);
    return false;

  19. Cheryl H. says:

    Very nice, clear example for a difficult topic. Thank you for posting.

  20. Weng says:

    May i ask how to run then example? Thank you!

  21. Gaurav Sachdeva says:

    Hi Joe, Really nice article. However, I am facing an issue that I am getting ModelAndView as null in postHandle method of my interceptor. ANy ideas to resolve that? Really appreciated.

  22. bipin kumar says:

    how we can use HTML file as view(output page) in Spring MVC Application.

    In spring MVC Application the Spring Controller will always use .jsp file, then how we can use HTML file in place of .jsp file.
    thanks.

  23. Shirish says:

    Hey Joe,

    I have slightly deviating problem, in my case i need to create a session scoped bean per user ….. and let spring handle the session for me!

  24. selvam says:

    Hi Joe,

    I want to create a centralized single PARENT controller for all child classes which need to fill full the following cases,
    1) Execute() method for common functionality for all screens
    2) Forward() method tells that which page need to go.
    3) One common abstract method to be used for the extended CHILD classes where they can explore on their specific functionality.
    Let say CHILD1, CHILD2, etc extends PARENT class.
    For any action comes, container first look at PARENT class to execute the methods then it will come to the CHILD class to execute abstract method.
    For this case, interceptor is right concept to adapt this case.
    Kindly suggest.

  25. samsonsunny says:

    nice explanation. thanks

  26. sneh says:

    Hey !

    Thanks for the article .
    Could you even please mention how do we configure the interceptors within the spring config java file as opposed to the xml file.

    if it enough to use component-scan on the base package of the interceptor or do we also have to add it with the registery object ?

    – thanks.

Comments are closed for this "Spring MVC Handler Interceptor" tutorial.