package com.api.aspect;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson.JSON;
import com.antong.common.util.DateUtil;
/**
* Copyright: Copyright (c) 2018 zq_tuo
*
* @ClassName: WebLogAspect.java
* @Description: AOP统一处理Web请求日志
使用@Aspect注解将一个java类定义为切面类
使用@Pointcut定义一个切入点,可以是一个规则表达式,比如下例中某个package下的所有函数,也可以是一个注解等。
根据需要在切入点不同位置的切入内容
使用@Before在切入点开始处切入内容
使用@After在切入点结尾处切入内容
使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
使用@Around在切入点前后切入内容,并自己控制何时执行切入点自身的内容
使用@AfterThrowing用来处理当切入内容部分抛出异常之后的处理逻辑
*
* @version: v1.0.0
* @author: tuozq
* @date: 2018年6月26日 下午4:03:43
* Modification History:
* Date Author Version Description
*---------------------------------------------------------*
* 2018年6月26日 tuozq v1.0.0 修改原因
*/
@Aspect
@Component
public class WebLogAspect {
private Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
@Value("${api.devMode}")
private boolean devMode;
ThreadLocal<Long> startTime = new ThreadLocal<>();
@Pointcut("execution(public * com.antong.api.web..*.*(..))")
public void webLog(){}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
if(devMode) {
// 接收到请求,记录请求内容
startTime.set(System.currentTimeMillis());
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Signature signature = joinPoint.getSignature();
//MethodSignature methodSignature = (MethodSignature) signature;
StringBuilder sb = new StringBuilder("\n\nAction report -------- ").append(DateUtil.format(new Date())).append(" -----------------------------------\n");
sb.append("Url : ").append(request.getMethod()).append(" ").append(request.getRequestURI()).append("\n");
sb.append("Controller : ").append(signature.getDeclaringTypeName()).append(".(").append(signature.getDeclaringType().getSimpleName()).append(".java:1)");
sb.append("\nMethod : ").append(signature.getName()).append("\n");
Enumeration<String> enumeration = request.getParameterNames();
Map<String,String> parameterMap = new HashMap<>();
while (enumeration.hasMoreElements()){
String parameter = enumeration.nextElement();
parameterMap.put(parameter,request.getParameter(parameter));
}
String str = JSON.toJSONString(parameterMap);
if(str.length() > 0) {
sb.append("UrlPara : ").append(str).append("\n");
}
sb.append("--------------------------------------------------------------------------------\n");
logger.debug(sb.toString());
}
}
@AfterReturning(returning = "ret", pointcut = "webLog()")
public void doAfterReturning(Object ret) throws Throwable {
if(devMode) {
// 处理完请求,返回内容
logger.debug("RESPONSE : " + ret);
logger.debug("SPEND TIME : " + (System.currentTimeMillis() - startTime.get()));
}
}
}