Spring MVC 使用介绍(四)—— 拦截器
一、概述
1、接口定义
拦截器由HandlerInterceptor接口定义:
public interface HandlerInterceptor { // 预处理方法 boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; // 后处理方法 void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; // 请求结束后处理方法 void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception; }
详细说明:
- preHandle:预处理方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器;返回值:
- true:表示继续流程(如调用下一个拦截器或处理器)
- false:表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应
- postHandle:后处理方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null
- afterCompletion:整个请求处理完毕处理方法,即在视图渲染完毕时调用,可以进行性能监控或资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion
2、运行流程
正常流程:
中断流程:
详细可参考DispatcherServlet.doDispatch()方法源码
二、简单示例
拦截器
spring提供HandlerInterceptorAdapter适配器,提供HandlerInterceptor接口空的实现,允许我们只实现需要的方法,因此拦截器可继承自该接口
public class TestInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("this is preHandle"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("this is postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("this is afterCompletion"); } }
控制器
public class TestController2 implements Controller { public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("this is TestController2"); return new ModelAndView("hello2"); } }
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>test-servlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>test-servlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
spring-mvc.xml:注册拦截器和控制器
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <!-- HandlerMapping --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="testInterceptor"/> </list> </property> </bean> <!-- HandlerAdapter --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!-- ViewResolver --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean name="/hello2" class="cn.matt.controller.TestController2"/> <bean name="testInterceptor" class="cn.matt.interceptor.TestInterceptor"/> </beans>
hello2.jsp
<%@ page language="java" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> hello2 </body> </html>
访问http://localhost:8080/myweb/hello2,控制台输出:
this is preHandle this is TestController2 this is postHandle this is afterCompletion
推荐能使用servlet规范中的过滤器Filter实现的功能就用Filter实现,因为HandlerInteceptor只有在Spring Web MVC环境下才能使用,因此Filter是最通用的、最先应该使用的,详细使用可参考javaweb学习总结(四十二)——Filter(过滤器)学习
参考:
javaweb学习总结(四十二)——Filter(过滤器)学习