Spring MVC HandlerInterceptor Example
June 28, 2019
On this page we will provide Spring MVC HandlerInterceptor example with WebMvcConfigurerAdapter. Spring HandlerInterceptor works similar to the Servlet Filter. Servlet filters are more powerful than Spring HandlerInterceptor. Servlet Filters are configured in web.xml and Spring HandlerInterceptor is configured in Spring application context xml file or Java configuration. Spring HandlerInterceptor can be used to avoid repetitive handler code. We can use HandlerInterceptor for different purposes like authorization checks, locale checks etc. In java configuration, WebMvcConfigurerAdapter has a method as addInterceptors in which InterceptorRegistry is passed as an argument. Using InterceptorRegistry.addInterceptor(), we add our interceptors and using InterceptorRegistry.addInterceptor().addPathPatterns(), we provide path pattern specific to given interceptor. If an interceptor has not been provided with any path pattern, it is called for each request. Spring provides HandlerInterceptorAdapter adapter class for implementing only required handler methods of HandlerInterceptor. HandlerInterceptor has three methods.
preHandle(): It is executed before actual handler is executed.
postHandle(): It is executed after handler is executed.
afterCompletion(): It is executed after the complete request is finished.
In our example, we are creating two interceptors, one using HandlerInterceptor and another using HandlerInterceptorAdapter. In our controller, we are creating two methods with different path pattern. We will configuie our interceptors one without any path pattern and another with a specific path pattern.
Software Used
Find the software and tool, which are using in our demo.1. Java 7
2. Tomcat 8
3. Eclipse
4. Gradle
5. Spring 4
Project Structure in Eclipse
Find the project structure in eclipse.Gradle File to Resolve Dependencies
Find the Gradle used to resolve JAR dependencies.build.gradle
apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'war' archivesBaseName = 'concretepage' version = '1' repositories { mavenCentral() } dependencies { compile 'org.springframework.boot:spring-boot-starter-web:1.2.2.RELEASE' compile 'jstl:jstl:1.2' providedCompile 'org.springframework.boot:spring-boot-starter-tomcat:1.2.2.RELEASE' }
Interceptor using HandlerInterceptor
We will create the Interceptor implementing HandlerInterceptor interface. We need to override all the three methods preHandle(), postHandle() and afterCompletion(). For the example, we have create an interceptor for logging.LoggingInterceptor.java
package com.concretepage.interceptors; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class LoggingInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("---Before Method Execution---"); return true; } @Override public void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("---method executed---"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("---Request Completed---"); } }
Interceptor using HandlerInterceptorAdapter
Spring provides adapter class as HandlerInterceptorAdapter of HandlerInterceptor interface. Using adapter class, we can implement only required methods. In our example, we are creating interceptor for transaction methods and using the preHandle() implementation of HandlerInterceptorAdapter.TransactionInterceptor.java
package com.concretepage.interceptors; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class TransactionInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Got request to save data : name:"+request.getParameter("name")); return true; } }
Java Configuration Class with WebMvcConfigurerAdapter.addInterceptors()
In java configuration class, we need to extend WebMvcConfigurerAdapter. To add our interceptor, we override WebMvcConfigurerAdapter. addInterceptors() method. Find the code snippet.@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoggingInterceptor()); registry.addInterceptor(new TransactionInterceptor()).addPathPatterns("/person/save/*"); }
AppConfig.java
package com.concretepage.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.JstlView; import org.springframework.web.servlet.view.UrlBasedViewResolver; import com.concretepage.interceptors.LoggingInterceptor; import com.concretepage.interceptors.TransactionInterceptor; @Configuration @ComponentScan("com.concretepage") @EnableWebMvc public class AppConfig extends WebMvcConfigurerAdapter { @Bean public UrlBasedViewResolver setupViewResolver() { UrlBasedViewResolver resolver = new UrlBasedViewResolver(); resolver.setPrefix("/views/"); resolver.setSuffix(".jsp"); resolver.setViewClass(JstlView.class); return resolver; } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoggingInterceptor()); registry.addInterceptor(new TransactionInterceptor()).addPathPatterns("/person/save/*"); } }
Create WebApplicationInitializer Class
Find WebApplicationInitializer class implementation for spring DispatcherServlet initialization.WebAppInitializer.java
package com.concretepage.config; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRegistration.Dynamic; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; public class WebAppInitializer implements WebApplicationInitializer { public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(AppConfig.class); ctx.setServletContext(servletContext); Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx)); dynamic.addMapping("/"); dynamic.setLoadOnStartup(1); } }
Create Controller Class
In the controller we are creating two methods, one of which will be mapped with the path pattern defined for TransactionInterceptor.PersonController.java
package com.concretepage; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller @RequestMapping("/person") public class PersonController { @RequestMapping("/welcome") public String hello(Model model) { System.out.println("Welcome Friends!"); model.addAttribute("msg", "Welcome Friends!"); return "result"; } @RequestMapping("/save/info") public String savePerson(@RequestParam(value="name") String name, Model model) { System.out.println("Person Saved, name:"+ name); model.addAttribute("msg", "Request Processed"); return "result"; } }
result.jsp
<html> <head> <title>Spring MVC</title> </head> <body> <h1>${msg}</h1> </body> </html>
Output
Find the console output for the URLhttp://localhost:8080/concretepage-1/person/welcome
Here only LoggingInterceptor will work.
---Before Method Execution--- Welcome Friends! ---method executed--- ---Request Completed---
http://localhost:8080/concretepage-1/person/save/info?name=Ram
Here LoggingInterceptor and TransactionInterceptor both will work.
---Before Method Execution--- Got request to save data : name:Ram Person Saved, name:Ram ---method executed--- ---Request Completed---