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 ProjectDependencies 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
|