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>
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>
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 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"; } }
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>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/