<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.chinadrtv.uam.web.interceptors.LogWebHandlerInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
import java.lang.reflect.Array;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.chinadrtv.uam.utils.RequestUUIDHolder;
import com.chinadrtv.uam.utils.StopWatchHolder;
public class LogWebHandlerInterceptor implements HandlerInterceptor {
/**
* Logger for this class
*/
private static final Logger logger = LoggerFactory.getLogger(LogWebHandlerInterceptor.class);
private static final String DELIMITERS = ",; \t\n";
private static final String[] DEFAULT_EXCLUDE_STRINGS = {
"org.springframework", "spring_security", ".FILTERED", "javax.servlet" };
private String[] excludeStrings = DEFAULT_EXCLUDE_STRINGS;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod hm = (HandlerMethod) handler;
String call = hm.getBean().getClass().getName() + "." + hm.getMethod().getName() + "()";
logger.info("***** {} ***** Request [{}] for URI ({}).",
new Object[] { RequestUUIDHolder.get(), call, request.getRequestURI() });
} else {
logger.info("***** {} ***** Process for URI ({}).",
RequestUUIDHolder.get(), request.getRequestURI());
}
StringBuilder sb = new StringBuilder();
Iterator<Entry<String, String[]>> iter = request.getParameterMap().entrySet().iterator();
while (iter.hasNext()) {
Entry<String, String[]> entry = iter.next();
write(sb, entry.getKey(), entry.getValue());
}
logger.info("***** {} ***** Parameters of request : ({}). ", RequestUUIDHolder.get(), sb.toString());
sb = new StringBuilder();
for (Enumeration<String> en = request.getAttributeNames(); en.hasMoreElements();) {
String key = en.nextElement();
if (isExclude(key))
continue; // 有非用户字段跳过
write(sb, key, request.getAttribute(key));
}
logger.info("***** {} ***** Attributes of request : ({}). ", RequestUUIDHolder.get(), sb.toString());
StopWatchHolder.start();
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
long invokeTime = StopWatchHolder.getTime();
logger.info("***** {} ***** Invoke method completed in {} ms ",
RequestUUIDHolder.get(), invokeTime);
StopWatchHolder.reset();
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
long renderTime = StopWatchHolder.getTime();
logger.info("***** {} ***** Render view completed in {} ms ",
RequestUUIDHolder.get(), renderTime);
// 页面渲染完成后删除请求上下文的UUID
RequestUUIDHolder.remove();
StopWatchHolder.remove();
}
public void setExcludeString(String str) {
if (StringUtils.isNotEmpty(str)) {
excludeStrings = org.springframework.util.StringUtils
.tokenizeToStringArray(str, DELIMITERS, true, true);
}
}
// 文本输出
private void write(StringBuilder sb, String key, Object value) {
sb.append("[");
sb.append(key);
sb.append(" : ");
sb.append(isArray(value) ? writeArray(value) : value);
sb.append("]");
}
// 将数组的各个元素值输出
private String writeArray(Object value) {
StringBuilder sb = new StringBuilder();
int length = Array.getLength(value);
for (int pos = 0; pos < length; pos++) {
sb.append(Array.get(value, pos));
sb.append(pos == length -1 ? "" : ",");
}
return sb.toString();
}
// 判断是否是数组
private boolean isArray(Object value) {
return value != null && value.getClass().isArray();
}
// 判断是否是应该排除的字段
private boolean isExclude(String name) {
for (String key : excludeStrings) {
if (StringUtils.contains(name, key)) return true;
}
return false;
}
}
分享到:
相关推荐
在Java中,有两种主要的方式来实现拦截器:一种是基于接口的JDK动态代理,另一种是基于类的CGLIB动态代理。这里我们将深入探讨这两种方式以及与责任链模式的关系。 首先,让我们理解什么是拦截器。拦截器是一种设计...
Struts2.X 拦截器是Apache Struts框架的核心组件之一,它是基于拦截器模式实现的,使得开发者能够方便地扩展和定制应用程序的行为。在Struts2中,拦截器扮演着中间件的角色,它在Action执行前后进行处理,可以进行如...
在这个例子中,`logInvocation`方法作为拦截器,会在`someBusinessMethod`调用前后打印日志信息。 **6. 结合源码和工具** 理解EJB拦截器的工作原理,可以通过查看EJB容器(如TomEE、GlassFish、WildFly)的源码,...
由于文件数量有限,以下将基于日志分析和崩溃拦截这两个主题展开详细介绍。 首先,我们来看日志分析。在Android系统中,标准的日志系统是Logcat,它提供了打印、过滤和搜索等功能,但有时这不足以满足复杂的调试...
在Struts2中,拦截器是基于Java的动态代理机制实现的,它们按照预定义的顺序对请求进行拦截并处理。拦截器链是由多个拦截器组成的,每个拦截器都有“around”行为,即在目标方法执行前后执行特定的任务。 创建一个...
你将看到拦截器在方法调用前后打印的日志消息,证明拦截器已经成功工作。 通过这个简单的示例,你可以了解到JavaEE拦截器的基本用法。在实际开发中,拦截器可以用于更复杂的场景,比如统一的异常处理、性能统计、...
拦截器主要用于实现通用功能,如权限验证、日志记录、性能监控等,从而提高代码的可复用性和模块化。 在Spring MVC中,拦截器是通过实现`HandlerInterceptor`接口或继承`AbstractHandlerInterceptor`抽象类来创建的...
1. **CXF Interceptors机制**:CXF采用了一种基于拦截器的架构,允许开发者在消息处理的不同阶段插入自定义的行为。这些拦截器可以被用来执行各种任务,比如安全检查、日志记录等。 2. **Logging Message**:CXF内部...
上述代码中,`logging`拦截器会在Action执行前后打印日志,`myStack`拦截器栈包含默认拦截器栈和`logging`拦截器,`someAction`会使用这个拦截器栈。 接下来,我们关注描述中提到的注解使用。Struts2在`...
现在,每当有请求经过,我们的拦截器就会打印相应的日志信息,实现了简单的请求跟踪。 为了更好地利用拦截器,你可以考虑以下几点: 1. **拦截策略**:可以根据URL模式、请求方法或其他条件来决定哪些请求需要被...
现在,当控制器中的方法被调用时,我们的日志拦截器就会按预期工作,记录下方法执行的详细信息。 通过这种方式,我们能够优雅地在不修改原有业务代码的情况下,实现对日志的统一管理和控制,提高了代码的可维护性和...
该项目为基于Java和HTML实现的OpenLinkLog日志链路跟踪拦截设计源码,包含111个文件,涵盖66个Java源文件...该设计通过拦截主流框架请求并添加traceId,利用slf4j的MDC功能将信息打印至日志,实现系统间日志链路跟踪。
拦截器允许开发者在对象状态变化时执行自定义逻辑,比如更新时间戳、记录审计日志等。 #### 定义拦截器 拦截器是通过实现 `Interceptor` 接口来创建的。在本示例中,定义了一个名为 `MyInterceptor` 的拦截器类,...
5. **StackTrace拦截器**:在发生异常时,打印堆栈跟踪信息。 **拦截器的配置** 在struts.xml配置文件中,可以使用`<interceptors>`标签定义全局拦截器,也可以在具体的Action配置中使用`<interceptor-ref>`引用...
提供单独的基于 OkHttp 的日志拦截器,能够打印 Request、Response 信息,便于网络接口的调试。 适用人群:学习不同技术领域的小白或进阶学习者;可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。
这是一个基于Okhttp网络请求框架的网络拦截器,代码是用了开源项目的大神打印代码,输出很好用的网络日志。使用方式:放入你使用的okhttp网络请求框架中,然后通过添加拦截器的方式添加拦截,格式化打印日志。
Spring MVC中的拦截器是基于AOP(面向切面编程)思想实现的。当一个请求到达时,Spring MVC会按照配置的拦截器顺序依次调用每个拦截器的`preHandle()`方法。如果所有拦截器都允许请求继续,那么Spring MVC会执行对应...
本示例主要探讨的是如何利用Spring AOP的注解式编程来实现请求和返回日志的自动打印。首先,我们需要配置Spring的AOP代理。`springmvc-servlet.xml`和`applicationContext.xml`是Spring的配置文件,通常会包含AOP的...
这可能是通过拦截器或者自定义处理器实现的,确保对外发送的数据安全。 3. **基于注解的脱敏方式**:注解是Java中的元数据,可以用来标记代码以执行特定的操作。在日志脱敏场景下,开发者可以在敏感字段上添加注解...
拦截器监控慢SQL并将完整的可执行的SQL语句打印在日志文件中,复制该SQL语句即可在数据库工具中执行。 使用方法: 找到你springboot项目中的配置文件,增加如下配置即可 application.yml 配置如下: sql: slow...