什麼是 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>