接口请求参数和返回参数打印

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";

    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值