文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

springboot 启动项目打印接口列表

环境

修改配置文件


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

结果:

在这里插入图片描述

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

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

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

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

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


@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ParamInfo {
    
    boolean unPrint() default false;
    
    String[] fields() default {};
}

自定义序列化规则



public class ReplaceFieldFilter implements ValueFilter {
    
    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);
        }
    }
}

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

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯