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>
相关文章
相关标签/搜索