• spring拦截器的简单实现Interceptor


    原文链接:http://lixuanbin.iteye.com/blog/2250100

    1. 需求描述

       某内部管理系统采用Spring MVC搭建,用户可以登录系统进行CRUD以及其他的一些日常管理操作。现在希望对某些敏感操作(譬如修改重要数据)进行拦截,在日志中记录下该操作的执行人,操作时间,操作名称,传入参数以及返回结果等信息,以便万一出问题后追究查验。

       

    2. 解决思路

       有两种方案:

    (1)把对应的MVC方法使用AOP去拦截,这个是方法级别的拦截;

    (2)使用Spring MVC Interceptor去拦截,这个是基于URL的拦截。

       那么,如何选择呢?考虑到我们这个是WEB项目,只有登录用户才能执行管理操作,而登录用户的用户信息一般放在Session里,使用基于URL拦截的方法便于提取Session数据;而且,被Spring MVC @Controller注解的类,都被AnnotationMethodHandlerAdapter给代理了,使用AOP进行拦截的话需要做些特殊处理。所以,在这里我们选择使用Interceptor拦截。

    3. 具体实现

    (1)Spring配置文件

       在beans头部标签加入:

    ...

    xmlns:mvc="http://www.springframework.org/schema/mvc"

    ...

    xsi:schemaLocation="...

    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd

    ..."

       然后加上mvc:interceptors拦截声明:

    Xml代码  收藏代码
     1 <mvc:interceptors>  
     2     <mvc:interceptor>  
     3         <mvc:mapping path="/**"/><!--拦截所有controller-->  
     4         <mvc:exclude-mapping  path="/js/**" />  
     5         <mvc:exclude-mapping  path="/css/**" />  
     6         <mvc:exclude-mapping  path="/img/**" />  
     7         <mvc:exclude-mapping  path="*.woff" />  
     8         <mvc:exclude-mapping  path="*.ico" />  
     9         <mvc:exclude-mapping  path="*.swf" />  
    10         <mvc:exclude-mapping  path="*.png" />  
    11         <bean id="log4UpdateOrDeleteInterceptor"  
    12 class="com.XXX.testmvc.interceptor.Log4UpdateOrDeleteInterceptor"></bean>  
    13     </mvc:interceptor>  
    14 </mvc:interceptors>  
        Spring的拦截路径采用了AntPathMatcher的方式。以下是引用自官方的说明:

    The mapping matches URLs using the following rules:

    • ? matches one character
    • * matches zero or more characters
    • ** matches zero or more 'directories' in a path

    Some examples:

    • com/t?st.jsp - matches com/test.jsp but also com/tast.jsp or com/txst.jsp
    • com/*.jsp - matches all .jsp files in the com directory
    • com/**/test.jsp - matches all test.jsp files underneath the com path
    • org/springframework/**/*.jsp - matches all .jsp files underneath the org/springframework path
    • org/**/servlet/bla.jsp - matches org/springframework/servlet/bla.jsp but also org/springframework/testing/servlet/bla.jsp and org/servlet/bla.jsp

    (2)实现拦截器

       继承HandlerInterceptorAdapter并按需覆写里面的preHandle和postHandle方法即可。

    Java代码  收藏代码
     1 /** 
     2  * 拦截敏感操作并记录到日志 
     3  *  
     4  * @author 5  */  
     6 public class Log4UpdateOrDeleteInterceptor extends HandlerInterceptorAdapter {  
     7     protected static final Logger log = Logger.getLogger(Log4UpdateOrDeleteInterceptor.class);  
     8   
     9     public boolean preHandle(HttpServletRequest request, HttpServletResponse response,  
    10             Object handler) throws Exception {  
    11         HttpSession session = request.getSession();  
    12         String requestUri = request.getRequestURI();  
    13         log.debug("request uri:" + requestUri);  
    14         String contextPath = request.getContextPath();  
    15         String url = requestUri.substring(contextPath.length());  
    16         if (StringUtils.contains(url, "add") || StringUtils.contains(url, "edit")  
    17                 || StringUtils.contains(url, "delete")) {  
    18             String user = session.getAttribute(SessionKey.USERNAME_SESSION_NAME) != null ? (String) session  
    19                     .getAttribute(SessionKey.USERNAME_SESSION_NAME) : null;  
    20             StringBuffer sb = new StringBuffer();  
    21             Enumeration<String> a = null;  
    22             a = request.getParameterNames();  
    23             while (a.hasMoreElements()) {  
    24                 String key = a.nextElement();  
    25                 sb.append(key + ":" + request.getParameter(key) + ", ");  
    26             }  
    27             log.warn(String.format("FBI request warning! user: %s, url: %s, params: {%s}", user,  
    28                     url, StringUtils.removeEnd(StringUtils.trim(sb.toString()), ",")));  
    29         }  
    30         return true;  
    31     }  
    32   
    33     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o,  
    34             ModelAndView mav) throws Exception {  
    35         HttpSession session = request.getSession();  
    36         String requestUri = request.getRequestURI();  
    37         log.debug("request uri:" + requestUri);  
    38         String contextPath = request.getContextPath();  
    39         String url = requestUri.substring(contextPath.length());  
    40         if ((StringUtils.contains(url, "add") || StringUtils.contains(url, "edit") || StringUtils  
    41                 .contains(url, "delete")) && mav != null) {  
    42             String user = session.getAttribute(SessionKey.USERNAME_SESSION_NAME) != null ? (String) session  
    43                     .getAttribute(SessionKey.USERNAME_SESSION_NAME) : null;  
    44             Map<String, Object> map = mav.getModel();  
    45             StringBuffer sb = new StringBuffer();  
    46             for (Map.Entry<String, Object> entry : map.entrySet()) {  
    47                 sb.append(entry.getKey() + ":"  
    48                         + (entry.getValue() != null ? entry.getValue().toString() : null) + ", ");  
    49             }  
    50             log.warn(String.format("FBI response warning! user: %s, url: %s, models: {%s}", user,  
    51                     url, StringUtils.removeEnd(StringUtils.trim(sb.toString()), ",")));  
    52         }  
    53     }  
    54   
    55     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o,  
    56             Exception excptn) throws Exception {  
    57         // System.out.println("afterCompletion");  
    58     }  
    59   
    60 }  

        本例检查URI是否含有敏感操作来判断是否需要进行日志记录,如果您采用了REST接口,也可以加上request method的校验。

  • 相关阅读:
    [转]C++ Operator Overloading Guidelines
    SICP学习笔记(2.2.1)
    .net中模拟键盘和鼠标操作
    javaScript系列 [17]运算符
    javaScript系列 [24]Math
    javaScript系列 [19]string
    javaScript系列 [22]引用类型
    javaScript系列 [12]Canvas绘图(曲线)
    javaScript系列 [15]Canvas绘图(压缩)
    javaScript系列 [21]Array
  • 原文地址:https://www.cnblogs.com/protected/p/6655986.html
Copyright © 2020-2023  润新知