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

网友投稿 581 2022-12-09

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

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

目录springboot 启动项目打印接口列表环境修改配置文件Springboot项目添加接口入参统一打印新建注解,用于实现参数打印功能的增强自定义序列化规则写参数打印增强,这里选择环绕增强

springboot 启动项目打印接口列表

环境

springboot 2.3.2.RELEASE

修改配置文rAMAapGrcy件

logging:

level:

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: trace

结果:

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 {

/**

* 需http://要进行替换的属性名和替换值

* key:属性名

* value:替换值

*/

private Map fieldMap;

public ReplaceFieldFilter() {

}

public ReplaceFieldFilter(Map fieldMap) {

this.fieldMap = fieldMap;

}

@Override

public Object process(Object o, String name, Object value) {

if(!CollectionUtils.isEmpty(fieldMap)){

Iterator> iterator = fieldMap.entrySet().iterator();

while (iterator.hasNext()){

Map.Entry next = iterator.next();

if(next.getKey().equalsIgnoreCase(name)){

return next.getValue();

}

}

}

return value;

}

public Map getFieldMap() {

return fieldMap;

}

public void setFieldMap(Map 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 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 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);

}

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java page cache回写机制案例详解
下一篇:mybatis条件语句中带数组参数的处理
相关文章

 发表评论

暂时没有评论,来抢沙发吧~