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 lixuanbin
*/
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的校验。
4. 参考资料:
http://docs.spring.io/spring/docs/3.0.x/javadoc-api/org/springframework/util/AntPathMatcher.html
http://www.oschina.net/question/222929_124314
分享到:
相关推荐
首先,了解拦截器(Interceptor)在Spring MVC中的角色。拦截器是Spring MVC提供的一种AOP(面向切面编程)特性,允许我们在请求处理之前、之后或者在视图渲染之后进行一些预处理或后处理操作。我们可以利用拦截器来...
拦截器(Interceptor)是Spring MVC中的一种机制,可以在请求处理前、后执行自定义逻辑。通过实现HandlerInterceptor接口或使用@Interceptor注解,开发者可以添加全局的行为,如日志记录、权限检查等。 此外,...
在Spring MVC框架中,拦截器(Interceptor)是一个强大的工具,用于在请求被控制器处理之前、之后以及视图渲染之后执行一些额外的操作。拦截器通过实现`HandlerInterceptor`接口或者继承`HandlerInterceptorAdapter`...
Spring MVC 框架中的拦截器(Interceptor)是一种重要的组件,它主要用于处理请求与响应的生命周期,提供了一种灵活的方式来实现诸如权限检查、日志记录、性能监控等功能。拦截器在请求到达控制器(Controller)之前...
在Spring MVC框架中,拦截器(Interceptor)是一个至关重要的组件,它允许开发者在请求处理之前、之后或在处理过程中执行自定义逻辑。拦截器可以用于实现日志记录、权限检查、性能统计、事务管理等多种功能,极大地...
要使用Spring MVC,首先需要在项目中引入Spring MVC的依赖,并配置Spring的DispatcherServlet,它是Spring MVC的前端控制器,负责调度请求到相应的处理器。 3. **Controller** Controller是处理请求的组件,通常...
9. **Interceptor**: 拦截器可以用来在请求处理前后执行一些通用操作,如权限检查、日志记录等。 10. **Conversion and Validation**: Spring MVC提供了数据转换和验证功能,如使用`@RequestParam`、`@PathVariable...
9. **拦截器(Interceptor)**: Spring MVC允许自定义拦截器,可以在请求处理前或后执行一些通用逻辑,如权限检查、日志记录等。 10. **异常处理**: 可以全局或局部地配置异常处理器,将异常转换为特定的视图或HTTP...
10. **拦截器(Interceptor)**:Spring MVC允许自定义拦截器,实现预处理和后处理功能,例如权限检查、日志记录等。 11. **转换器和格式化器(Converter & Formatter)**:处理请求参数和模型属性之间的类型转换,...
《精通Spring MVC4》这本书是Java开发者们的重要参考资料,它深入浅出地讲解了Spring MVC这一强大框架的各个方面。Spring MVC是Spring框架的一个模块,专为构建Web应用程序而设计,以其灵活性、高效性和可扩展性受到...
在Spring MVC框架中,拦截器(Interceptor)是一个强大的工具,用于在请求被控制器处理之前或之后执行特定的逻辑。它们可以用来实现权限检查、日志记录、性能统计等多种功能。本压缩包“spring mvc 拦截器获取请求...
12. **Interceptor**:拦截器,允许在请求处理前后执行自定义逻辑,如日志记录、权限检查等。 13. **View Technologies**:Spring MVC支持多种视图技术,如JSP、Thymeleaf、FreeMarker等,可以根据项目需求选择。 ...
而Interceptor(拦截器)则是Spring MVC提供的一种强大的机制,它允许我们在请求处理之前或之后执行一些自定义逻辑,比如权限验证、日志记录、性能统计等。在"spring mvc annotation interceptor"这个主题中,我们将...
7. **拦截器**:自定义Interceptor,实现请求前后的预处理和后处理,如权限控制、日志记录等。 8. **RESTful支持**:通过@RequestMapping的HTTP方法参数支持GET、POST、PUT、DELETE等操作。 9. **模板引擎集成**:与...
本篇文章将深入探讨如何在Spring MVC中使用Interceptor拦截器。 首先,Interceptor的实现需要继承自`HandlerInterceptor`接口或者实现`HandlerInterceptorAdapter`适配器类,这两个类都包含三个核心方法: 1. `...
9. **拦截器(Interceptor)**:拦截器可以在请求处理前后执行自定义逻辑,例如日志记录、权限检查等。 10. **异常处理**:Spring MVC 提供了统一的异常处理机制,通过 @ExceptionHandler 或配置 ExceptionResolver...
接着,深入探讨了Spring MVC的高级特性,例如:拦截器(Interceptor)用于在请求处理前后执行自定义逻辑,视图解析器(ViewResolver)用于确定响应的视图,以及数据绑定和验证机制,这些能帮助开发者实现更灵活的...
10. **拦截器(Interceptor)**:Spring MVC允许定义拦截器,它们在请求被Controller处理之前和之后执行,可以用来实现日志记录、权限验证等功能。 11. **数据绑定**:Spring MVC提供自动的数据绑定功能,将HTTP...
拦截器(Interceptor)在Spring MVC中扮演着重要的角色,它们可以对HTTP请求进行预处理和后处理,例如记录日志、权限检查、性能统计等。下面将详细介绍创建和配置Spring MVC拦截器的步骤。 1. **创建自定义拦截器**...
- **Interceptor**:拦截器,可以在请求处理前后执行额外的操作,如权限验证、日志记录等。 ### 3. Spring MVC 工作流程 1. 用户发送 HTTP 请求到应用服务器。 2. DispatcherServlet 接收到请求,通过 ...