package com.xxx.xxx.aop;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Stopwatch;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @description:
* @author: zhanglao
* @date: 2022/3/25 7:24 下午
*/
@Component
@Aspect
@Slf4j
public class RequestAop{
/**
* @Description: 定义需要拦截的切面
* @Pointcut("execution(* com.*.controller.*Controller.*(..))")
* @Return: void
**/
@Pointcut("execution(* com.xxxx.facade.controller.*Controller.*(..))")
public void executeController() {
}
@Around("executeController()")
public Objectinvoke(ProceedingJoinPoint joinPoint) throws Throwable{
Object result;
Stopwatch stopwatch = Stopwatch.createStarted();
result = joinPoint.proceed();
try {
HttpServletRequest request =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// ip地址
String ipAddr = getRemoteHost(request);
// 请求路径
String requestUrl = request.getRequestURL().toString();
// 获取请求参数进行打印
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature =(MethodSignature) signature;
// 类名
// swagger中文注释名
String classCommentName = methodSignature.getMethod().getDeclaringClass().getAnnotation(Api.class).tags()[0];
String[] sourceName = signature.getDeclaringTypeName().split("\\.");
String className = sourceName[sourceName.length -1] +"[" + classCommentName +"]";
// 方法名
// swagger中文注释名
String methodCommentName = methodSignature.getMethod().getAnnotation(ApiOperation.class).value();
String methodName = signature.getName() +"[" + methodCommentName +"]";
// 参数名数组
String[] parameterNames =((MethodSignature) signature).getParameterNames();
// 构造参数组集合
List
for (Object arg : joinPoint.getArgs()) {
// request/response无法使用toJSON
if (arginstanceof HttpServletRequest) {
argList.add("request");
} else if (arginstanceof HttpServletResponse) {
argList.add("response");
} else {
argList.add(JSON.toJSON(arg));
}
}
stopwatch.stop();
long timeConsuming = stopwatch.elapsed(TimeUnit.MILLISECONDS);
log.error("请求源IP【{}】 -> 请求URL【{}】\n{} -> {} -> 请求耗时:[{}]毫秒 \n请求参数:{} -> {}\n请求结果:{}",
ipAddr, requestUrl,
className, methodName, timeConsuming,
JSON.toJSON(parameterNames), JSON.toJSON(argList),
JSON.toJSON(result));
} catch (Exception e) {
log.error("参数获取失败: {}", e.getMessage());
}
return result;
}
/**
* 获取目标主机的ip
* @param request
* @return
*/
private StringgetRemoteHost(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip ==null || ip.length() ==0 ||"unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip ==null || ip.length() ==0 ||"unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip ==null || ip.length() ==0 ||"unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip.contains("0:0:0:0:0:0:0:1") ?"127.0.0.1" : ip;
}
}