• 通过拦截器Interceptor实现Spring MVC中Controller接口访问信息的记录


    java web工程项目使用了Spring+Spring MVC+Hibernate的结构,在Controller中的方法都是用于处理前端的访问信息,Controller通过调用Service进行业务处理后给前端返回ModelAndView对象或者只返回Json格式数据。如果能够获得Http请求在后端程序中处理的相关信息,对于开发和调试时十分方便的。工程中使用了Spring MVC的Interceptor对所有Http请求及其响应进行拦截,从而获取到本次访问接口信息以及程序处理时长等信息,特意在此记录一下实现方式。

     1 package com.api.web.interceptor;
     2 
     3 import java.util.Arrays;
     4 import java.util.Date;
     5 import java.util.Map;
     6 import java.util.Map.Entry;
     7 
     8 import javax.servlet.http.HttpServletRequest;
     9 import javax.servlet.http.HttpServletResponse;
    10 
    11 import org.apache.log4j.Logger;
    12 import org.springframework.web.method.HandlerMethod;
    13 import org.springframework.web.servlet.HandlerInterceptor;
    14 import org.springframework.web.servlet.ModelAndView;
    15 
    16 import com.yijia.api.util.SimpleDateFormatCache;
    17 
    18 /**
    19  * 记录信息:</br> 访问时间</br>Controller路径</br>对应方法名</br>请求参数信息</br>请求相对路径</br>请求处理时长
    20  * 
    21  * @author Administrator
    22  * 
    23  */
    24 public class TimeCostInterceptor implements HandlerInterceptor {
    25 
    26     // before the actual handler will be executed
    27     public boolean preHandle(HttpServletRequest request,
    28             HttpServletResponse response, Object handler) throws Exception {
    29         long startTime = System.currentTimeMillis();
    30         request.setAttribute("startTime", startTime);
    31         if (handler instanceof HandlerMethod) {
    32             StringBuilder sb = new StringBuilder(1000);
    33 
    34             sb.append("-----------------------").append(SimpleDateFormatCache.getYmdhms().format(new Date()))
    35                     .append("-------------------------------------
    ");
    36             HandlerMethod h = (HandlerMethod) handler;
    37             sb.append("Controller: ").append(h.getBean().getClass().getName()).append("
    ");
    38             sb.append("Method    : ").append(h.getMethod().getName()).append("
    ");
    39             sb.append("Params    : ").append(getParamString(request.getParameterMap())).append("
    ");
    40             sb.append("URI       : ").append(request.getRequestURI()).append("
    ");
    41             System.out.println(sb.toString());
    42         }
    43         return true;
    44     }
    45 
    46     // after the handler is executed
    47     public void postHandle(HttpServletRequest request,
    48             HttpServletResponse response, Object handler,
    49             ModelAndView modelAndView) throws Exception {
    50         long startTime = (Long) request.getAttribute("startTime");
    51         long endTime = System.currentTimeMillis();
    52         long executeTime = endTime - startTime;
    53         if(handler instanceof HandlerMethod){
    54             StringBuilder sb = new StringBuilder(1000);
    55             sb.append("CostTime  : ").append(executeTime).append("ms").append("
    ");
    56             sb.append("-------------------------------------------------------------------------------");
    57             System.out.println(sb.toString());
    58         }
    59     }
    60 
    61     private String getParamString(Map<String, String[]> map) {
    62         StringBuilder sb = new StringBuilder();
    63         for(Entry<String,String[]> e:map.entrySet()){
    64             sb.append(e.getKey()).append("=");
    65             String[] value = e.getValue();
    66             if(value != null && value.length == 1){
    67                 sb.append(value[0]).append("	");
    68             }else{
    69                 sb.append(Arrays.toString(value)).append("	");
    70             }
    71         }
    72         return sb.toString();
    73     }
    74 
    75     public void afterCompletion(HttpServletRequest arg0,
    76             HttpServletResponse arg1, Object arg2, Exception arg3)
    77             throws Exception {
    78 
    79     }
    80 }

    由于Interceptor是Spring MVC的功能组件,所以需要把此拦截器配置在springmvc的xml配置文件中(或者使用其他配置方式比如javaConfig):

     <mvc:interceptors>
            <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
            <mvc:interceptor>
                <mvc:mapping path="/**"/>            
                <!-- 需排除拦截的地址 -->  
                <mvc:exclude-mapping path="/" />
                <mvc:exclude-mapping path="/test" />
                <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
                <bean class="com.api.web.interceptor.TimeCostInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>

    定义并配置好好拦截器后,在程序Controller中的接口被访问的时候,相关访问信息就会输出到控制台上,也可以使用日志将访问信息记录到日志中。

    记录效果如下所示:

    总结:

    拦截器通对用户请求进行拦截可以对用户的请求(HttpServletRequest)进行预处理,也可以对返回给用户的响应(HttpServletResponse)进行访问后处理,还可以在请求完成后针对请求的异常信息进行处理。能够在request对象和response对象中进行操作的问题都可以通过拦截器进行统一处理,常用的场景包括用户登录控制、权限检查,跨域请求访问权限控制等。 

  • 相关阅读:
    个人推荐网上商店
    vs 安装程序制作
    this linker was not configured to use sysroots和C compiler cannot create executables的解决办法
    将asihttprequest编译后的目标文件打包
    cygwin下的gcc4.7.1编译心得
    给ubuntu12.04换3.4.6的内核
    boost::asio::streambuf相关的操作方法
    应用boost库serialize标准库里的map
    cygwin下gdb7.4编译
    sql server存储过程分页,支持cte
  • 原文地址:https://www.cnblogs.com/gl-developer/p/5997508.html
Copyright © 2020-2023  润新知