欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

springboot 启动项目打印接口列表的实现

程序员文章站 2022-03-07 23:21:13
目录springboot项目添加接口入参统一打印springboot 启动项目打印接口列表环境 springboot 2.3.2.release修改配置文件logging: level:...

springboot 启动项目打印接口列表

环境

  • springboot 2.3.2.release

修改配置文件

logging:
  level:
    org.springframework.web.servlet.mvc.method.annotation.requestmappinghandlermapping: trace

结果:

springboot 启动项目打印接口列表的实现

springboot项目添加接口入参统一打印

需求:要求接口被调用时要打印被调用方法名,以及入参情况,参数格式化时选择fastjson

注:使用fastjson序列化时脱敏,建议入参统一使用自定义的对象类型作为入参

如果不需要参数脱敏,直接使用增强中相关代码,并去除参数脱敏相关代码即可

新建注解,用于实现参数打印功能的增强

@target({elementtype.method})
@retention(retentionpolicy.runtime)
@documented
public @interface paraminfo {
    /**
     * 取消统一打印参数
     * 默认为false统一打印
     * 如需自定义参数打印 请赋值为true
     */
    boolean unprint() default false;
    /**
     * 需要脱敏的字段,如密码等
     */
    string[] fields() default {};
}

自定义序列化规则

/**
 * 序列化过滤器:值替换
 *
 */
public class replacefieldfilter implements valuefilter {
    /**
     * 需要进行替换的属性名和替换值
     * key:属性名
     * value:替换值
     */
    private map<string, object> fieldmap;
    public replacefieldfilter() {
    }
    public replacefieldfilter(map<string, object> fieldmap) {
        this.fieldmap = fieldmap;
    }
    @override
    public object process(object o, string name, object value) {
        if(!collectionutils.isempty(fieldmap)){
            iterator<map.entry<string, object>> iterator = fieldmap.entryset().iterator();
            while (iterator.hasnext()){
                map.entry<string, object> next = iterator.next();
                if(next.getkey().equalsignorecase(name)){
                    return next.getvalue();
                }
            }
        }
        return value;
    }
    public map<string, object> getfieldmap() {
        return fieldmap;
    }
    public void setfieldmap(map<string, object> fieldmap) {
        this.fieldmap = fieldmap;
    }
    /**
     * 传入需要脱敏的字段名,序列化时格式化为 * 号
     */
    public replacefieldfilter(string... fields) {
        string str = "******";
        fieldmap = new hashmap<>(4);
        for (string field : fields) {
            fieldmap.put(field, str);
        }
    }
}

写参数打印增强,这里选择环绕增强

@component
@aspect
//表示增强的执行顺序,如果多个增强,数值小的先被执行
@order(0)
public class paraminfoaspect {
    private static final logger logger = loggerfactory.getlogger(paraminfoaspect.class);
    @around("execution(* com.service.impl.*.*(..))")
    public object printparam(proceedingjoinpoint joinpoint) throws throwable {
        long starttime = system.currenttimemillis();
        string requestid = randomstringutils.randomalphanumeric(16);
        object returnvalue = null;
        try {
            object[] args = joinpoint.getargs();
            // 获取方法对象
            methodsignature signature = (methodsignature) joinpoint.getsignature();
            method method = signature.getmethod();
            //通过注解获取脱敏字段,之后初始化fieldmap,完成字段脱敏
            paraminfo annotation = method.getannotation(paraminfo.class);
            map<string, object> fieldmap = new hashmap<>(4);
            fieldmap.put("password", "******");
            if (annotation != null) {
                //获取需要脱敏的字段名数组
                string[] fields = annotation.fields();
                for (string field : fields) {
                    fieldmap.put(field, "******");
                }
            }
            string param;
            //参数整合,多字段入参整合为对象,单个对象入参格式不变
            if (args.length > 1 || (args.length == 1 && args[0].getclass() == string.class)) {
                map<string, object> parammap = new linkedhashmap<>();
                string[] parameternames = signature.getparameternames();
                for (int i = 0; i < parameternames.length; i++) {
                    parammap.put(parameternames[i], args[i]);
                }
                param = "[" + json.tojsonstring(parammap, new replacefieldfilter(fieldmap)) + "]";
            } else {
                param = json.tojsonstring(args, new replacefieldfilter(fieldmap));
            }
            string methodname = method.getname();
            logger.info("method:[{}], parameter:{}, requestid:[{}]", methodname, param, requestid);
            returnvalue = joinpoint.proceed();
            return returnvalue;
        } catch (exception e) {
            logger.error("system is error:", e);
   //可在这里定义程序异常时的错误返回值
            returnvalue = errorcode.system_error;
            return returnvalue;
        } finally {
            logger.info("request cost:{}ms, requestid:[{}]", system.currenttimemillis() - starttime, requestid);
            logger.info("returnvalue:[{}], requestid:[{}]", returnvalue, requestid);
        }
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。