package com.xm.demo.aop.common.aspect;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import cn.hutool.core.util.IdUtil;
/**
* @author mengxc
* @ClassName: LoggerAspect
* @Description: 打印请求参数和返回结果
* @date 2020年12月9日 上午10:22:35
*/
@Aspect
@Configuration
@Order(-9)
@ConditionalOnProperty(value = "print.enable", havingValue = "true", matchIfMissing = false)
public class PrintAspect {
private static final Logger log = LoggerFactory.getLogger(PrintAspect.class);
// 定义切点Pointcut
@Pointcut("execution(* com.xm.demo.aop.controller.*.*(..))")
public void executeService() {
}
@Around("executeService()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
String uuid = IdUtil.fastSimpleUUID().toUpperCase();
try {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
// String url = request.getRequestURL().toString();
String method = request.getMethod();
String uri = request.getRequestURI();
String queryString = request.getQueryString();
Object[] args = pjp.getArgs();
String params = "";
// 获取请求参数集合并进行遍历拼接
if (args.length > 0) {
if ("POST".equals(method) || "PUT".equals(method) || "DELETE".equals(method)) {
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < args.length; i++) {
Object object = args[i];
Map<String, Object> mapObj = getKeyAndValue(object);
if (!mapObj.isEmpty()) {
map.putAll(mapObj);
}
}
try {
params = JSON.toJSONString(map);
JSONObject obj = JSONObject.parseObject(params);
params = "\n" + JSON.toJSONString(obj, SerializerFeature.PrettyFormat,
SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);
} catch (Exception e) {
try {
params = JSON.toJSONString(map);
} catch (Exception exception) {
log.error("打印参数解析异常");
}
}
} else if ("GET".equals(method)) {
if (StringUtils.isNotEmpty(queryString)) {
params = URLDecoder.decode(queryString, "UTF-8");
}
}
}
log.info(" \n===============================请求->开始===============================" + "\n追踪标记:" + uuid
+ "\n请求地址:" + uri + "\n请求类型:" + method + "\n请求参数:" + params
+ "\n===============================请求->结束===============================");
// result的值就是被拦截方法的返回值
Object result = null;
result = pjp.proceed();
log.info(" \n===============================返回值->开始===============================" + "\n追踪标记:" + uuid
+ "\n请求地址:" + uri + "\n返回值:" + JSON.toJSON(result)
+ "\n===============================返回值->结束===============================");
return result;
} catch (Exception e) {
log.info(" \n===============================请求异常->开始===============================" + "\n追踪标记:" + uuid
+ "\n异常信息:" + e + "\n===============================请求异常->结束===============================");
}
return pjp.proceed();
}
public static Map<String, Object> getKeyAndValue(Object obj) {
Map<String, Object> map = new HashMap<>();
if (obj instanceof MultipartFile || obj instanceof ServletRequest || obj instanceof ServletResponse) {
log.debug("MultipartFile|HttpServletRequest|HttpServletResponse参数");
return map;
}
try {
// 得到类对象
Class<?> userCla = obj.getClass();
/* 得到类中的所有属性集合 */
Field[] fs = userCla.getDeclaredFields();
for (Field f : fs) {
f.setAccessible(true); // 设置些属性是可以访问的
Object val;
try {
val = f.get(obj);
// 得到此属性的值
map.put(f.getName(), val);// 设置键值
} catch (IllegalArgumentException | IllegalAccessException e) {
log.error("异常", e);
}
}
} catch (Exception e) {
log.error("【异常】解析对象异常");
}
return map;
}
}