原文链接: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拦截声明:

 <mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/><!--拦截所有controller-->
<mvc:exclude-mapping path="/js/**" />
<mvc:exclude-mapping path="/css/**" />
<mvc:exclude-mapping path="/img/**" />
<mvc:exclude-mapping path="*.woff" />
<mvc:exclude-mapping path="*.ico" />
<mvc:exclude-mapping path="*.swf" />
<mvc:exclude-mapping path="*.png" />
<bean id="log4UpdateOrDeleteInterceptor"
class="com.XXX.testmvc.interceptor.Log4UpdateOrDeleteInterceptor"></bean>
</mvc:interceptor>
</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方法即可。

 /**
* 拦截敏感操作并记录到日志
*
* @author */
public class Log4UpdateOrDeleteInterceptor extends HandlerInterceptorAdapter {
protected static final Logger log = Logger.getLogger(Log4UpdateOrDeleteInterceptor.class); public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
HttpSession session = request.getSession();
String requestUri = request.getRequestURI();
log.debug("request uri:" + requestUri);
String contextPath = request.getContextPath();
String url = requestUri.substring(contextPath.length());
if (StringUtils.contains(url, "add") || StringUtils.contains(url, "edit")
|| StringUtils.contains(url, "delete")) {
String user = session.getAttribute(SessionKey.USERNAME_SESSION_NAME) != null ? (String) session
.getAttribute(SessionKey.USERNAME_SESSION_NAME) : null;
StringBuffer sb = new StringBuffer();
Enumeration<String> a = null;
a = request.getParameterNames();
while (a.hasMoreElements()) {
String key = a.nextElement();
sb.append(key + ":" + request.getParameter(key) + ", ");
}
log.warn(String.format("FBI request warning! user: %s, url: %s, params: {%s}", user,
url, StringUtils.removeEnd(StringUtils.trim(sb.toString()), ",")));
}
return true;
} public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o,
ModelAndView mav) throws Exception {
HttpSession session = request.getSession();
String requestUri = request.getRequestURI();
log.debug("request uri:" + requestUri);
String contextPath = request.getContextPath();
String url = requestUri.substring(contextPath.length());
if ((StringUtils.contains(url, "add") || StringUtils.contains(url, "edit") || StringUtils
.contains(url, "delete")) && mav != null) {
String user = session.getAttribute(SessionKey.USERNAME_SESSION_NAME) != null ? (String) session
.getAttribute(SessionKey.USERNAME_SESSION_NAME) : null;
Map<String, Object> map = mav.getModel();
StringBuffer sb = new StringBuffer();
for (Map.Entry<String, Object> entry : map.entrySet()) {
sb.append(entry.getKey() + ":"
+ (entry.getValue() != null ? entry.getValue().toString() : null) + ", ");
}
log.warn(String.format("FBI response warning! user: %s, url: %s, models: {%s}", user,
url, StringUtils.removeEnd(StringUtils.trim(sb.toString()), ",")));
}
} public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o,
Exception excptn) throws Exception {
// System.out.println("afterCompletion");
} }

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

spring拦截器的简单实现Interceptor的更多相关文章

  1. web 过滤器 Filter、 Spring 拦截器 interceptor

    1.过滤器(Filter)(在web.xml中注册过滤器) 首先说一下Filter的使用地方,我们在配置web.xml时,总会配置下面一段设置字符编码,不然会导致乱码问题: <filter> ...

  2. Java结合SpringBoot拦截器实现简单的登录认证模块

    Java结合SpringBoot拦截器实现简单的登录认证模块 之前在做项目时需要实现一个简单的登录认证的功能,就寻思着使用Spring Boot的拦截器来实现,在此记录一下我的整个实现过程,源码见文章 ...

  3. spring拦截器-过滤器的区别

    1.  理解 拦截器 :是在面向切面编程的时候,在你的 service 或者一个方法前调用一个方法,或者在方法后调用一个方法:比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业 ...

  4. Spring 拦截器实现+后台原理(HandlerInterceptor)

    过滤器跟拦截器的区别 spring mvc的拦截器是只拦截controller而不拦截jsp,html 页面文件的.这就用到过滤器filter了,filter是在servlet前执行的,你也可以理解成 ...

  5. spring拦截器的定义

    (一).拦截器的定义 1.为什么需要拦截器:在做身份认证或者是进行日志的记录时,我们需要通过拦截器达到我们的目的 2.什么事拦截器:在AOP(Aspect-Oriented Programming)中 ...

  6. Spring拦截器中通过request获取到该请求对应Controller中的method对象

    背景:项目使用Spring 3.1.0.RELEASE,从dao到Controller层全部是基于注解配置.我的需求是想在自定义的Spring拦截器中通过request获取到该请求对应于Control ...

  7. spring拦截器中修改响应消息头

    问题描述 前后端分离的项目,前端使用Vue,后端使用Spring MVC. 显然,需要解决浏览器跨域访问数据限制的问题,在此使用CROS协议解决. 由于该项目我在中期加入的,主要负责集成shiro框架 ...

  8. Spring拦截器和过滤器

    什么是拦截器 拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在方法执行之前或之后加入某些操作,其实就是AOP的一种实现策略.它通过动态拦截Action调用的对象,允许开发者 ...

  9. Spring 拦截器的使用

    一.Web.xml配置 在Web.xml 配置Spring核心控制器DispatcherServlet接收所有请求 <servlet> <servlet-name>spring ...

随机推荐

  1. Go基础之--排序和查找操作

    排序操作主要都在sort包中,导入就可以使用了import("sort") 常用的操作 sort.Ints:对整数进行排序sort.Strings:对字符串进行排序sort.Flo ...

  2. ORM规约变更经典案例---mysql军规

    先介绍一下<MySQL数据库开发的三十六条军规>,这里只介绍核心的,具体内容大家可以自行百度,这是从底层开发人员到管理者必须知道规范.出自58赶集. 写在前面的话: 总是在灾难发生后,才想 ...

  3. Windows Server 2016-Powershell迁移FSMO角色

    上一章节我们讲到了通过Ntdsutil命令行进行FSMO角色迁移,本章开始之前我们先讨论一下有关FSMO角色放置建议: 建议将架构主机角色(Schema Master)和域命名主机角色(Domain ...

  4. Linux下配置SNAT上网

    局域网有一台主机A,没有公网的IP, 也就是没有办法直接连到互联网上下载东西,同时内网有另外一台主机B,有公网接入.这个时候为了让A连接到互联网,我把B设置成NAT主机,A的网关指向B.准确的来说,现 ...

  5. Kubernetes 概念整理

    注:以下大部分内容来自网上摘录,以便后期查阅. Kubernetes (通常称为 K8s) 是用于自动部署.扩展和管理容器化(containerized)应用程序的开源系统,是 Google 内部工具 ...

  6. 《android开发艺术探索》读书笔记(十四)--JNI和NDK编程

    接上篇<android开发艺术探索>读书笔记(十三)--综合技术 No1: Java JNI--Java Native Interface(java本地接口),它是为了方便java调用C. ...

  7. POJ - 3268 单源最短路

    题意:给定一些有向边,以及一个目的地,从某个点到达目的地,再从目的地回到那个点.共有n个点,问这n个点花费最大是多少? 思路:从目的地回去直接把目的地作为源点即可.那么从某个点到达目的地应该如何得到最 ...

  8. HDU - 2160 递推

    思路:dp(i)表示第i天的猪的数量,g(i)表示第i天新出生的猪的数量,d(i) = d(i-1) * 2 - g(i-2), g(i) = d(i-1) AC代码 #include <cst ...

  9. 《python机器学习—预测分析核心算法》笔记1

    参见原书 1.1-1.4节 一.惩罚线性回归模型 基本特性: 1.训练时间快,使用训练好的模型进行预测的时间也快2.应用于高速交易.互联网广告的植入等3.解决回归.分类问题 最重要的特性:能明确指出, ...

  10. 【Elasticsearch全文搜索引擎实战】之集群搭建及配置

    文中Elasticsearch版本为6.0.1 1. 环境配置 把环境配置放在第一节来讲,是因为很多人按官网的Getting Started安装运行会有各种错误.其实都是因为一些配置不正确引起的. 首 ...