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拦截声明:
<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>
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
- matchescom/test.jsp
but alsocom/tast.jsp
orcom/txst.jsp
com/*.jsp
- matches all.jsp
files in thecom
directorycom/**/test.jsp
- matches alltest.jsp
files underneath thecom
pathorg/springframework/**/*.jsp
- matches all.jsp
files underneath theorg/springframework
pathorg/**/servlet/bla.jsp
- matchesorg/springframework/servlet/bla.jsp
but alsoorg/springframework/testing/servlet/bla.jsp
andorg/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的更多相关文章
- web 过滤器 Filter、 Spring 拦截器 interceptor
1.过滤器(Filter)(在web.xml中注册过滤器) 首先说一下Filter的使用地方,我们在配置web.xml时,总会配置下面一段设置字符编码,不然会导致乱码问题: <filter> ...
- Java结合SpringBoot拦截器实现简单的登录认证模块
Java结合SpringBoot拦截器实现简单的登录认证模块 之前在做项目时需要实现一个简单的登录认证的功能,就寻思着使用Spring Boot的拦截器来实现,在此记录一下我的整个实现过程,源码见文章 ...
- spring拦截器-过滤器的区别
1. 理解 拦截器 :是在面向切面编程的时候,在你的 service 或者一个方法前调用一个方法,或者在方法后调用一个方法:比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业 ...
- Spring 拦截器实现+后台原理(HandlerInterceptor)
过滤器跟拦截器的区别 spring mvc的拦截器是只拦截controller而不拦截jsp,html 页面文件的.这就用到过滤器filter了,filter是在servlet前执行的,你也可以理解成 ...
- spring拦截器的定义
(一).拦截器的定义 1.为什么需要拦截器:在做身份认证或者是进行日志的记录时,我们需要通过拦截器达到我们的目的 2.什么事拦截器:在AOP(Aspect-Oriented Programming)中 ...
- Spring拦截器中通过request获取到该请求对应Controller中的method对象
背景:项目使用Spring 3.1.0.RELEASE,从dao到Controller层全部是基于注解配置.我的需求是想在自定义的Spring拦截器中通过request获取到该请求对应于Control ...
- spring拦截器中修改响应消息头
问题描述 前后端分离的项目,前端使用Vue,后端使用Spring MVC. 显然,需要解决浏览器跨域访问数据限制的问题,在此使用CROS协议解决. 由于该项目我在中期加入的,主要负责集成shiro框架 ...
- Spring拦截器和过滤器
什么是拦截器 拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在方法执行之前或之后加入某些操作,其实就是AOP的一种实现策略.它通过动态拦截Action调用的对象,允许开发者 ...
- Spring 拦截器的使用
一.Web.xml配置 在Web.xml 配置Spring核心控制器DispatcherServlet接收所有请求 <servlet> <servlet-name>spring ...
随机推荐
- Swift百万线程攻破单例(Singleton)模式
一.不安全的单例实现 在上一篇文章我们给出了单例的设计模式,直接给出了线程安全的实现方法.单例的实现有多种方法,如下面: class SwiftSingleton { class var shared ...
- python学习:简单的wc命令实现
#!/usr/bin/python import sys import os try: fn = sys.argv[1] except IndexError: print &q ...
- 【学习笔记】Hibernate 一对一关联映射 组件映射 二级缓存 集合缓存
啊讲道理放假这十天不到啊 感觉生活中充满了绝望 这就又开学了 好吧好吧继续学习笔记?还是什么的 一对一关联映射 这次我们仍然准备了两个表 一个是用户表Users 一个是档案表Resume 他们的关系是 ...
- C#获取文件夹下的所有文件的文件名(转载)
String path = @"X:\xxx\xxx"; //第一种方法 var files = Directory.GetFiles(path, "*.txt&qu ...
- linux开放80 端口
1.使用su登录管理员用户 2.编辑防火墙配置文件 vim /etc/sysconfig/iptables 3.在里面加入后保存 #open port 80 -A INPUT -p TCP -m st ...
- linux中/bin和/sbin和/usr/bin和/usr/sbin
首先先解释一下bin和sbin的意思: 1.bin:为任何用户都可以使用的指令 2.sbin:(super bin)也就是只有超级管理员才能使用的指令 /usr UNIX Software Re ...
- Spring-mvc 静态资源不拦截
在Spring-mvc.xml文件中加入这个就可以了 <!-- 用于对静态文件进行解析 --> <mvc:annotation-driven /> <mvc:resour ...
- 4.3 lambda表达式
函数,封装的代码块可以很复杂,也可以很简单.当函数的代码块简单到只有一个表达式,就可以考虑用lambda表达式,也称匿名函数. 1 lambda表达式基础 #首先需要声明一点:lambda是表达式而非 ...
- 1 Python数据类型--
常见的Python数据类型: (1)数值类型:就是平时处理的数字(整数.浮点数) (2)序列类型:有一系列的对象并排或者排列的情况.如字符串(str),列表(list),元组(tuple)等 (3)集 ...
- CNN 卷积层输入Map大小计算
对于输出的size计算: out_height=((input_height - filter_height + padding_top+padding_bottom)/stride_height ) ...