spring mvc inteceptor 攔截器實現計算controller 的執行時間 異常處理

什麼是 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>
相關文章
相關標籤/搜索