Spring MVC – Phần 9: Interceptor, Filter trong Spring MVC. So sánh Interceptor với Filter
1. Spring Interceptor
Trong Spring MVC hỗ trợ 1 tính năng khá giống với Filter trong JSP-Server đó là Interceptor.
Interceptor thực hiện lọc các request được xử lý bởi controller.
Mỗi request gửi đến 1 URL được xử lý bởi controller có thể đi qua không, một hoặc nhiều Interceptor.
Interceptor sẽ kiểm tra thông tin request (thông tin đăng nhập, session, ip…) để cho phép request đi qua hoặc từ chối request, chuyển hướng request

Code ví dụ:

Thư viện sử dụng:
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>stackjava.com</groupId>
- <artifactId>SpringMVCInterceptor</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>war</packaging>
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>5.0.2.RELEASE</version>
- </dependency>
- </dependencies>
- </project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>stackjava.com</groupId>
<artifactId>SpringMVCInterceptor</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>stackjava.com</groupId>
<artifactId>SpringMVCInterceptor</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
</project>
File Config Spring
- <?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:context="http://www.springframework.org/schema/context"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
- 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-4.3.xsd">
- <context:component-scan base-package="stackjava.com.springmvchello" />
- <bean
- class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix">
- <value>/WEB-INF/views/jsp/</value>
- </property>
- <property name="suffix">
- <value>.jsp</value>
- </property>
- </bean>
- <!-- Configuring interceptors based on URI -->
- <mvc:interceptors>
- <mvc:interceptor>
- <mvc:mapping path="/**" />
- <bean class="stackjava.com.springmvchello.interceptor.LogTimeInterceptor" />
- </mvc:interceptor>
- <mvc:interceptor>
- <mvc:mapping path="/spring/**" />
- <!-- <mvc:exclude-mapping path="/spring/abc"/> -->
- <bean class="stackjava.com.springmvchello.interceptor.ClientInfoInterceptor" />
- </mvc:interceptor>
- </mvc:interceptors>
- </beans>
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
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-4.3.xsd">
<context:component-scan base-package="stackjava.com.springmvchello" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<!-- Configuring interceptors based on URI -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="stackjava.com.springmvchello.interceptor.LogTimeInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/spring/**" />
<!-- <mvc:exclude-mapping path="/spring/abc"/> -->
<bean class="stackjava.com.springmvchello.interceptor.ClientInfoInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
</beans>
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
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-4.3.xsd">
<context:component-scan base-package="stackjava.com.springmvchello" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<!-- Configuring interceptors based on URI -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="stackjava.com.springmvchello.interceptor.LogTimeInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/spring/**" />
<!-- <mvc:exclude-mapping path="/spring/abc"/> -->
<bean class="stackjava.com.springmvchello.interceptor.ClientInfoInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
</beans>
Các interceptor sẽ được khai báo trong thẻ <mvc:interceptor>
Thẻ <mvc:mapping> khai báo các url sẽ đi qua interceptor (có thể khai báo nhiều thẻ <mvc:mapping> trong 1 thẻ <mvc:interceptor>
Thẻ <mvc:exclude> để bỏ qua các url khi thực hiện interceptor
Ví dụ trên: /** tức là tất cả các URL sẽ đi qua interceptor: LogTimeInterceptor
/spring/** tức là các URL bắt đầu bởi /spring/ sẽ đi qua interceptor: ClientInfoInterceptor
Các file Interceptor
- package stackjava.com.springmvchello.interceptor;
- import java.util.Date;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
- public class LogTimeInterceptor implements HandlerInterceptor{
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
- System.out.println("preHandle Log time Interceptor: " + request.getServletPath() + new Date());
- return true;
- }
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
- ModelAndView modelAndView) throws Exception {
- System.out.println("postHandle Log time Interceptor: " + request.getServletPath() + new Date());
-
- }
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
- throws Exception {
- System.out.println("afterCompletion Log time Interceptor: " + request.getServletPath() + new Date());
-
- }
- }
package stackjava.com.springmvchello.interceptor;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class LogTimeInterceptor implements HandlerInterceptor{
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("preHandle Log time Interceptor: " + request.getServletPath() + new Date());
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle Log time Interceptor: " + request.getServletPath() + new Date());
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion Log time Interceptor: " + request.getServletPath() + new Date());
}
}
package stackjava.com.springmvchello.interceptor;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class LogTimeInterceptor implements HandlerInterceptor{
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("preHandle Log time Interceptor: " + request.getServletPath() + new Date());
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle Log time Interceptor: " + request.getServletPath() + new Date());
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion Log time Interceptor: " + request.getServletPath() + new Date());
}
}
- ClientInfoInterceptor.java
- package stackjava.com.springmvchello.interceptor;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
- public class ClientInfoInterceptor implements HandlerInterceptor {
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
- System.out.println("preHandle ClientInfoInterceptor: ip " + request.getRemoteHost() + " language: " + request.getLocale());
- return true;
- }
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
- ModelAndView modelAndView) throws Exception {
- }
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
- throws Exception {
- }
- }
package stackjava.com.springmvchello.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class ClientInfoInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("preHandle ClientInfoInterceptor: ip " + request.getRemoteHost() + " language: " + request.getLocale());
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
package stackjava.com.springmvchello.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class ClientInfoInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("preHandle ClientInfoInterceptor: ip " + request.getRemoteHost() + " language: " + request.getLocale());
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
Để tạo 1 Interceptor ta implement org.springframework.web.servlet.HandlerInterceptor
1 Interceptor sẽ gồm 3 method:
- preHandle: xử lý trước khi request tới controller, nếu trả về false thì request sẽ không được gửi tới controller
- postHandle: xử lý sau khi request tới controller
- afterCompletion: thực hiện sau khi request hoàn thành
Controller
- package stackjava.com.springmvchello.controller;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- @Controller
- public class HelloController {
- @RequestMapping("/")
- public String index() {
- return "index";
- }
- @RequestMapping(value = "/spring/test", method = RequestMethod.GET)
- public String hello() {
- return "test";
- }
- }
package stackjava.com.springmvchello.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class HelloController {
@RequestMapping("/")
public String index() {
return "index";
}
@RequestMapping(value = "/spring/test", method = RequestMethod.GET)
public String hello() {
return "test";
}
}
package stackjava.com.springmvchello.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class HelloController {
@RequestMapping("/")
public String index() {
return "index";
}
@RequestMapping(value = "/spring/test", method = RequestMethod.GET)
public String hello() {
return "test";
}
}
View:
- <html>
- <head>
- <title>index</title>
- </head>
- <body>
- <h1>Spring MVC Interceptor!</h1>
- <a href="spring/test">/spring/test</a>
- </body>
- </html>
<html>
<head>
<title>index</title>
</head>
<body>
<h1>Spring MVC Interceptor!</h1>
<a href="spring/test">/spring/test</a>
</body>
</html>
<html>
<head>
<title>index</title>
</head>
<body>
<h1>Spring MVC Interceptor!</h1>
<a href="spring/test">/spring/test</a>
</body>
</html>
- <html>
- <head>
- <title>test</title>
- </head>
- <body>
- <h1>/spring/test</h1>
- </body>
- </html>
<html>
<head>
<title>test</title>
</head>
<body>
<h1>/spring/test</h1>
</body>
</html>
<html>
<head>
<title>test</title>
</head>
<body>
<h1>/spring/test</h1>
</body>
</html>
Demo:

Kết quả

2. So sánh Spring Interceptor với Filter
Okay, Done!
Download code ví dụ trên tại đây
References:
https://justforchangesake.wordpress.com/2014/05/07/spring-mvc-request-life-cycle/
https://gopalakrishnadurga.wordpress.com/2012/06/08/filter-vs-interceptor/
Spring MVC – Phần 9: Interceptor, Filter trong Spring MVC. So sánh Interceptor với Filter