Close

Spring MVC - HandlerMapping#setInterceptors() vs InterceptorRegistry#addInterceptor()

[Last Updated: Dec 7, 2017]

In this tutorial, we will understand the difference between the two ways of registering HandlerInterceptors.

To register a HandlerInterceptor with a HandlerMapping, we need to use Abstract Handler Mapping# set Interceptors(. . . . ) as we saw in the last tutorial.

There's another way of registering HandlerInterceptors, i.e. to extend our Java config class with WebMvcConfigurerAdapter, override addInterceptors method and then use Interceptor Registry# add Interceptor(. . . ) as seen in this example.

The difference

AbstractHandlerMapping#setInterceptors(....), sets the interceptors to only one HandlerMapping. The interceptors, in this case, are applied to all handlers mapped by this AbstractHandlerMapping.

Registering interceptors via WebMvcConfigurerAdapter, will register the interceptor with default HandlerMappings (i.e. RequestMappingHandlerMapping and BeanNameUrlHandlerMapping at the time of writing this tutorial) and additionally to the ViewControllerRegistry (check out this tutorial). If interested, you can check out the source code of WebMvcConfigurationSupport and look for the method getInterceptors() references. The default HandlerMappings, in fact, use the same method AbstractHandlerMapping#setInterceptors to register the interceptors returned by getInterceptors() call. The method getInterceptors() eventually calls back (in DelegatingWebMvcConfiguration actually) our configuration class (which implements WebMvcConfigurerAdapter). Check out this quick tutorial as well to get familiar with @EnableWebMvc configuration.

Example

In this example, we will register a HandlerInterceptor to SimpleUrlHandlerMapping and to default HandlerMappings too (via InterceptorRegistry#addInterceptor method):

Creating an interceptor

public class MyInterceptor extends HandlerInterceptorAdapter {
  
  @Override
  public boolean preHandle (HttpServletRequest request,
                            HttpServletResponse response,
                            Object handler) throws Exception {
      
      System.out.println("preHandle, URI: " + request.getRequestURI());
      return true;
  }
  
  @Override
  public void postHandle (HttpServletRequest request, HttpServletResponse response,
                          Object handler, ModelAndView modelAndView) throws Exception {
      System.out.println("postHandle, URI: " + request.getRequestURI());
  }
}

Registering interceptor

@EnableWebMvc
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
  
  @Bean
  public SimpleUrlHandlerMapping simpleUrlHandlerMapping () {
      SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
      Map<String, Object> map = new HashMap<>();
      map.put("/app", httpRequestHandler());
      mapping.setUrlMap(map);
      mapping.setInterceptors(new Object[]{new MyInterceptor()});
      return mapping;
  }
  
  @Bean
  HttpRequestHandler httpRequestHandler () {
      return new MyHttpRequestHandler();
  }
  
  @Override
  public void addInterceptors (InterceptorRegistry registry) {
      InterceptorRegistration ir = registry.addInterceptor(new MyInterceptor());
  }
  
  @Bean
  ExampleController controller () {
      return new ExampleController();
  }
}

The handler

public class MyHttpRequestHandler implements HttpRequestHandler {
  
  @Override
  public void handleRequest (HttpServletRequest request,
                             HttpServletResponse response)
            throws ServletException, IOException {
      System.out.println("handling request in MyHttpRequestHandler");
      PrintWriter writer = response.getWriter();
      writer.write("response from MyHttpRequestHandler, uri: " + request.getRequestURI());
  }
}

The @Controller

@Controller
public class ExampleController {

  @RequestMapping("/example")
  @ResponseBody
  public String handleRequest () {
      System.out.println("in the controller");
      return "response from /example";
  }
}

To try examples, run embedded tomcat (configured in pom.xml of example project below):

mvn tomcat7:run-war

Output

Accessing the URI '/example', which will invoke our @Controller via RequestMappingHandlerMapping.

Output on the server console:

preHandle, URI: /example
in the controller
postHandle, URI: /example
In this case InterceptorRegistry#addInterceptor is responsible for the interceptor registration (if we skip this registration, the interceptor won't be called).

Now let's try the URI '/app', which will invoke our MyHttpRequestHandler via SimpleUrlHandlerMapping:

Output on the server console:

preHandle, URI: /app
handling request in MyHttpRequestHandler
postHandle, URI: /app

Example Project

Dependencies and Technologies Used:

  • spring-webmvc 4.2.4.RELEASE: Spring Web MVC.
  • spring-test 4.2.4.RELEASE: Spring TestContext Framework.
  • javax.servlet-api 3.0.1 Java Servlet API
  • junit 4.12: JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck.
  • JDK 1.8
  • Maven 3.3.9

Handler Interceptors Registration Example Project Select All Download
  • handler-interceptors-registration
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • AppConfig.java

    See Also