package com.chuangjie.treasure.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import static com.chuangjie.treasure.utils.ParamsPrintUtils.ParamPrintProperty.*;
@Slf4j
@Aspect
@Component
public class ParamsPrintUtils {
@Around("execution(* com.chuangjie.*.controller.*.*(..))")
public Object print(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
printMethodParams(proceedingJoinPoint);
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (Objects.isNull(requestAttributes)) {
return null;
}
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
log.info(REQUEST_ADDRESS + request.getRequestURL().toString());
log.info(REQUEST_METHOD_TYPE + request.getMethod());
Object resultValue = proceedingJoinPoint.proceed();
printMethodResultValue(resultValue);
return resultValue;
}
private void printMethodParams(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Class<?> target = proceedingJoinPoint.getTarget().getClass();
String className = target.getName();
String methodName = proceedingJoinPoint.getSignature().getName();
log.info(API_THE_METHOD_CALLED_IS, methodName);
// 获取方法名称
String[] paramsArgsNames = getFieldsName(className, methodName);
// 获取方法的参数组
Object[] paramsArgsValue = proceedingJoinPoint.getArgs();
if (ArrayUtils.isNotEmpty(paramsArgsNames) || ArrayUtils.isNotEmpty(paramsArgsValue)) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < paramsArgsNames.length; i++) {
//参数名
String name = paramsArgsNames[i];
if (!REQUEST.equals(name) && !RESPONSE.equals(name)) {
//参数值
Object value = paramsArgsValue[i];
value = value == null ? "null" : value;
buffer.append(0 == i ? WRAP + PREFIX_PRINT_01 + PREFIX_PRINT_02 + name + EQUAL : PREFIX_PRINT_01
+ PREFIX_PRINT_02 + name + EQUAL);
Class<?> clazz = value.getClass();
buffer.append(clazz.isPrimitive() || clazz == String.class ? value + WRAP : value.toString() + WRAP);
}
}
log.info(buffer.toString());
}
}
/**
* 使用javassist来获取方法参数名称
*
* @param className 类名
* @param methodName 方法名
* @return
* @throws Exception
*/
private String[] getFieldsName(String className, String methodName) throws Exception {
Class<?> clazz = Class.forName(className);
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(clazz));
CtMethod ctMethod = pool.get(clazz.getName()).getDeclaredMethod(methodName);
CodeAttribute codeAttribute = ctMethod.getMethodInfo().getCodeAttribute();
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
if (Objects.isNull(attr)) {
return null;
}
String[] paramsArgsName = new String[ctMethod.getParameterTypes().length];
for (int i = 0; i < paramsArgsName.length; i++) {
paramsArgsName[i] = attr.variableName(i + (Modifier.isStatic(ctMethod.getModifiers()) ? 0 : 1));
}
return paramsArgsName;
}
/**
* 输出json
*
* @param object
*/
public void printMethodResultValue(Object object) {
JSONObject jsonObject = (JSONObject) JSON.toJSON(object);
if (null != jsonObject) {
String layOut = " ";
// JSON转字符串
String jsonStr = jsonObject.toString();
int level = 0;// 用户标记层级
// 新建stringbuffer对象,用户接收转化好的string字符串
StringBuffer resultValue = new StringBuffer();
for (int i = 0; i < jsonStr.length(); i++) {
char piece = jsonStr.charAt(i);
// 如果上一个字符是断行,则在本行开始按照level数值添加标记符,排除第一行
if (i != 0 && '\n' == resultValue.charAt(resultValue.length() - 1)) {
for (int k = 0; k < level; k++) {
resultValue.append(layOut);
}
}
switch (piece) {
case '{':
case '[':
// 如果字符是{或者[,则断行,level加1
resultValue.append(piece + WRAP);
level++;
break;
case ',':
// 如果是“,”,则断行
resultValue.append(piece + WRAP);
break;
case '}':
case ']':
// 如果是}或者],则断行,level减1
resultValue.append(WRAP);
level--;
for (int k = 0; k < level; k++) {
resultValue.append(layOut);
}
resultValue.append(piece);
break;
default:
resultValue.append(piece);
break;
}
}
log.info(WRAP + JSON_RESULT + WRAP + resultValue.toString());
}
}
static class ParamPrintProperty {
public static final String PREFIX_PRINT_01 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
public static final String PREFIX_PRINT_02 = ".999 INFO 99999 --- [io-8090-exec-99] c.c.treasure.utils.ParamsPrintUtils : ";
public static final String WRAP = "\n";
public static final String API_THE_METHOD_CALLED_IS = "Api The method called is -------------------> {}";
public static final String REQUEST_ADDRESS = "Request Address-------->:";
public static final String REQUEST_METHOD_TYPE = "Request Method Type---->:";
public static final String EQUAL = " = ";
public static final String JSON_RESULT = "Json Result:";
public static final String REQUEST = "request";
public static final String RESPONSE = "response";
}
}
接口请求参数和返回参数打印
最新推荐文章于 2024-08-28 01:27:08 发布