什么是 spring inteceptor , SpringMVC 中的Interceptor 拦截请求是经过HandlerInterceptor 来实现的。在SpringMVC 中定义一个Interceptor 很是简单,主要有两种方式,第一种方式是要定义的Interceptor类要实现了Spring 的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor 接口的类,好比Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ;第二种方式是实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。java
HandlerInterceptor接口中定义了三个方法,咱们就是经过这三个方法来对用户的请求进行拦截处理的。web
[java] view plain copy 在CODE上查看代码片派生到个人代码片spring
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class SpringMVCInterceptor implements HandlerInterceptor { /** * preHandle方法是进行处理器拦截用的,顾名思义,该方法将在Controller处理以前进行调用,SpringMVC中的Interceptor拦截器是链式的,能够同时存在 * 多个Interceptor,而后SpringMVC会根据声明的先后顺序一个接一个的执行,并且全部的Interceptor中的preHandle方法都会在 * Controller方法调用以前调用。SpringMVC的这种Interceptor链式结构也是能够进行中断的,这种中断方式是令preHandle的返 * 回值为false,当preHandle的返回值为false的时候整个请求就结束了。 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // TODO Auto-generated method stub return false; } /** * 这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。postHandle是进行处理器拦截用的,它的执行时间是在处理器进行处理之 * 后,也就是在Controller的方法调用以后执行,可是它会在DispatcherServlet进行视图的渲染以前执行,也就是说在这个方法中你能够对ModelAndView进行操 * 做。这个方法的链式结构跟正常访问的方向是相反的,也就是说先声明的Interceptor拦截器该方法反而会后调用,这跟Struts2里面的拦截器的执行过程有点像, * 只是Struts2里面的intercept方法中要手动的调用ActionInvocation的invoke方法,Struts2中调用ActionInvocation的invoke方法就是调用下一个Interceptor * 或者是调用action,而后要在Interceptor以前调用的内容都写在调用invoke以前,要在Interceptor以后调用的内容都写在调用invoke方法以后。 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub } /** * 该方法也是须要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。该方法将在整个请求完成以后,也就是DispatcherServlet渲染了视图执行, * 这个方法的主要做用是用于清理资源的,固然这个方法也只能在当前这个Interceptor的preHandle方法的返回值为true时才会执行。 Exception 参数表示的是当前请求的异常对象,若是在Controller 中抛出的异常已经被Spring 的异常处理器给处理了的话,那么这个异常对象就是是null 。 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub } }
这里我采用第一种方式来实现,首先实现HandlerInterceptor 接口: [java] view plain copy 在CODE上查看代码片派生到个人代码片apache
package com.inteceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import org.springframework.web.servlet.HandlerInterceptor; public class TimeInteceptor implements HandlerInterceptor{ private static final Logger logger = Logger.getLogger(TimeInteceptor.class); //before the actual handler will be executed public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { long startTime = System.currentTimeMillis(); request.setAttribute("startTime", startTime); return true; } //after the handler is executed public void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { long startTime = (Long)request.getAttribute("startTime"); long endTime = System.currentTimeMillis(); long executeTime = endTime - startTime; //modified the exisitng modelAndView modelAndView.addObject("executeTime",executeTime); //log it if(logger.isDebugEnabled()){ logger.debug("[" + handler + "] executeTime : " + executeTime + "ms"); } } public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { // TODO Auto-generated method stub } }
写了这个inteceptor 以后,怎么让它生效去拦截请求呢? 须要在spring mvc 的配置文件中去配置:spring-mvc
[java] view plain copy 在CODE上查看代码片派生到个人代码片mvc
<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd" default-autowire="byName"> <mvc:interceptors> <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截全部的请求 --> <bean class="com.inteceptor.AllInteceptor"/> <mvc:interceptor> <mvc:mapping path="/**"/> <!-- 需排除拦截的地址 --> <mvc:exclude-mapping path="/" /> <mvc:exclude-mapping path="/test" /> <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 --> <bean class="com.inteceptor.TimeInteceptor"/> </mvc:interceptor> </mvc:interceptors> </beans>