MVC

Spring MVC Interceptor Tutorial

In this tutorial, we are going to discuss about SpringMVC Interceptor. First, we discuss about Spring MVC architecture and where an interceptor is invoked in this architecture, then we have a look at the implementation of interceptor in more details.

1. Overview of Spring MVC Architecture

Spring’s web MVC framework is request-driven and designed based on a central Servlet that dispatches requests to controllers and invokes other functionality that facilitates the development of web applications.
 

 
The request processing workflow of the Spring MVC DispatcherServlet is illustrated in the following diagram.

Spring MVC Architecture
Spring MVC Architecture

The DispatcherServlet is an actual Servlet and inherits from the HttpServlet base class. When a request is sent to the web application, the workflow of handling a request is as below:

  • When DispatcherServlet receives the request, it dispatches the task of selecting an appropriate controller to HandlerMapping. Then, HandlerMapping selects the controller which is mapped to the incoming request URL and returns the (selected Handler) and Controller to DispatcherServlet.
  • DispatcherServlet dispatches the task of executing the business logic by Controller to HandlerAdapterHandlerAdapter calls the business logic process of Controller. When the HandlerAdapter calls the controller, Interceptor is invoked to intercept the request.
  • Then, Controller executes the business logic and sets the processing result in Model. Then, if there is any Interceptor to intercept the response, is invoked as a post process. Then Controller returns the logical name of view to HandlerAdapter.
  • DispatcherServlet dispatches the task of resolving the View corresponding to the View name to ViewResolver. ViewResolver returns the View mapped to View name.
  • DispatcherServlet dispatches the rendering process to returned View.
  • View renders Model data and returns the response.

2. Intercepting the request

Spring’s handler mapping mechanism includes handler interceptors, which are useful when you want to apply specific functionality to certain requests, for example, checking for a principal. Interceptors must implement HandlerInterceptor from the org.springframework.web.servlet package. This interface defines three methods:

  • preHandle is called before the actual handler is executed.
  • postHandle is called after the handler is executed.
  • afterCompletion is called after the complete request has finished.

These three methods should provide enough flexibility to do all kinds of pre-processing and post-processing.

The preHandle method returns a boolean value. You can use this method to break or continue the processing of the execution chain. When this method returnstrue, the handler execution chain will continue; when it returns false, the DispatcherServlet assumes the interceptor itself has taken care of requests (and, for example, rendered an appropriate view) and does not continue executing the other interceptors and the actual handler in the execution chain.

Question: What is the difference between Spring MVC Interceptor and Servlet Filter?

HandlerInterceptor is basically similar to a Servlet 2.5 Filter, but it just allows custom pre-processing with the option of prohibiting the execution of the Handler itself, and custom post-processing. Filters allow for exchanging the request and response objects that are passed to the chain. It means Filters work more in the request/response domain while HandlerInterceptors are spring bean and can access other beans in the application. Note that a Filter gets configured in web.xml, a HandlerInterceptor in the application context.

3. A Simple Interceptor tutorial

Now, lets have a look at this example to see how interceptor works in a web application. In the following example, I created a springMVC project in Spring Tool Suite 3.7.1 and used tomcat 8 as a web app server. The project is implemented based on java 1.7 and springMVC 4.1.1.

3.1. Create an interceptor

The AuthInterceptor implements HandlerInterceptor interface to handle the request before and after the controller. So, it implements all three methods of HandlerInterceptor. If there is no requirement for implementing the all three methods, it is recommended to extends HandlerInterceptorAdapter class instead.

In the following code, in the preHandle method, when the request method is GET, the request will be passed to the controller otherwise it won’t.

AuthInterceptor.java

package com.springapp.mvc;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.logging.Logger;

public class AuthInterceptor implements HandlerInterceptor {

    private static final Logger logger = Logger.getLogger("AuthInterceptor");

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        logger.info(" Pre handle ");
        if(httpServletRequest.getMethod().equals("GET"))
            return true;
        else
            return false;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        logger.info(" Post handle ");
        if(modelAndView.getModelMap().containsKey("status")){
            String status = (String) modelAndView.getModelMap().get("status");
            if(status.equals("SUCCESS!")){
                status = "Authentication " + status;
                modelAndView.getModelMap().put("status",status);
            }
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        logger.info(" After Completion ");
    }
}

In the postHandle method, status is checked and updated in ModelMap. Also, a message will be logged in the console when each method is executed.

Note that the postHandle method of HandlerInterceptor is not always ideally suited for use with @ResponseBody and ResponseEntity methods. In such cases an HttpMessageConverter writes to and commits the response before postHandle is called which makes it impossible to change the response, for example to add a header. Instead an application can implement ResponseBodyAdvice and either declare it as an @ControllerAdvice bean or configure it
directly onRequestMappingHandlerAdapter.

3.2. Spring MVC Interceptor Configuration

The interceptor must be configured in the mvc-dispatcher-servlet.xml. We can use mvc:interceptors element to wire all the interceptors. We can also provide URI pattern to match before including the interceptor for the request through mapping element.

The final spring bean configuration file looks like below.

mvc-dispatcher-servlet.xml

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

    <context:component-scan base-package="com.springapp.mvc"/>

    <mvc:interceptors>
            <bean class="com.springapp.mvc.AuthInterceptor" />
    </mvc:interceptors>

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

</beans>

3.2.1. Java Configuration of Interceptor

Interceptors can be also configured in java. See the below example of java configuration of interceptors (The following code is not available in the downloaded source code):

WebConfig.java

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
        registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
    }

}

3.3. Spring MVC Controller

The AuthController handle the request to the uri ‘/’, set the status and render the response to auth.jsp. The controller code is as below:

AuthController.java

package com.springapp.mvc;

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

import java.util.logging.Logger;

@Controller
@RequestMapping("/")
public class AuthController {

	private static final Logger logger = Logger.getLogger("AuthController");

	@RequestMapping(method = RequestMethod.GET)
	public String printStatus(ModelMap model) {
		logger.info("AuthController -> printStatus");
		model.addAttribute("status", "SUCCESS!");
		return "auth";
	}
}

3.4. Dependency configuration

The main dependency for Spring MVC is the spring-webmvc package. There are also other dependencies for log4j and servlet-api in the pom.xml file which you can find them in the source code of this tutorial.

pom.xml

      <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

3.5 Running the web application on Tomcat

After deploying the application to tomcat server, hit the http://localhost:8080/ and you can see the following message in the log and the result page is as below:

The log:

Spring MVC Interceptor Log
Spring MVC Interceptor Log

The result page:

Spring MVC Result Page
Spring MVC Result Page

4. Download the code project

This was an example of SpringMVC Interceptor in eclipse.

Tip
You can download the full source code of this example here: Spring MVC Interceptor Tutorial

Ima Miri

Ima is a Senior Software Developer in enterprise application design and development. She is experienced in high traffic websites for e-commerce, media and financial services. She is interested in new technologies and innovation area along with technical writing. Her main focus is on web architecture, web technologies, java/j2ee, Open source and mobile development for android.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button