• 自定义注解实现日志打印时屏蔽特定字段不打印


    需求:

    要求某接口的请求参数有一个字段不要在日志中打印

    方法1:

    前端传参和后端使用公钥密钥进行加密以后传输,后端业务执行的时候再解密;

    方法2:

    自定义注解在日志打印的时候屏蔽

    注解

    偷懒这里就不定义三种了准备这一个用到底了

    /**
     * 跳过Body请求参数日志打印
     */
    @Target({ElementType.METHOD,ElementType.PARAMETER,ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface SkipBodyParamLogPrint {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    日志aop的改造

    MethodSignature signature = (MethodSignature) pjp.getSignature();
    SkipBodyParamLogPrint skipBodyParamLog = signature.getMethod().getDeclaredAnnotation(SkipBodyParamLogPrint.class);
    if (ObjectUtil.isNotEmpty(skipBodyParamLog)) {
        // 如果有需要跳过的请求参数就执行检查
        args = paramSkipFilter(args);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    参数过滤方法

    /**
     * 检查是否需要跳过请求参数打印
     *
     * @return
     */
    public Object[] paramSkipFilter(Object[] args) {
        Object[] objects = Arrays.stream(args)
                .map(
                        arg -> {
                            // 获取所有字段
                            Field[] fields = arg.getClass().getDeclaredFields();
                            // 没有字段跳过
                            if (fields.length == 0)
                                return arg;
                            for (Field field : fields) {
                                // 字段如果有这注解就表示这个字段需要处理为空
                                SkipBodyParamLogPrint[] annotationsByType = field.getDeclaredAnnotationsByType(SkipBodyParamLogPrint.class);
                                if (annotationsByType.length != 0){
                                    try {
                                        // 拼接方法名
                                        String methodName = "set" + StringUtils.capitalize(field.getName());
                                        // 这里知道只有一个参数并且参数就是字段本身的类型就手动写了,其他地方需要用建议直接从数组匹配名称获得参数
                                        Method method = arg.getClass().getDeclaredMethod(methodName, field.getType());
                                        // 关闭安全检查
                                        field.setAccessible(true);
                                        // 执行方法,参数用字段类型进行实例化一个空对象,同样的如果其他地方需要用类似的方法,就从数组里获取方法然后取参数拼接数组传入
                                        method.invoke(arg,field.getType().newInstance());
                                        field.setAccessible(false);
                                    } catch (IllegalAccessException |InvocationTargetException e) {
                                        log.error("请求参数过滤时set方法调用失败",e);
                                        break;
                                    } catch (NoSuchMethodException | InstantiationException e) {
                                        log.error("请求参数过滤时set方法实例化失败",e);
                                        break;
                                    }
                                }
                            }
                            // 返回处理以后的参数
                            return arg;
                        }
                )
                .toArray();
        return objects;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    使用

    POJO

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ApiModel(value = "购买请求参数-purchase vip request parameters")
    public class BuyGoodsParam {
    
        @NotNull
        @ApiModelProperty(value = "商品类型,1音频课程,2直播课程,3vip订阅-Commodity type, 1 audio course, 2 live course, 3 vip subscription")
        private Integer goodsType;
    
        @NotNull
        @ApiModelProperty(value = "商品id-goods id")
        private Long goodsId;
    
        @NotBlank
        @ApiModelProperty(value = "交易类型,wechatPay:微信支付;aliPay:支付宝,stripe:Stripe",required = true)
        private String paymentType;
    
        @NotNull
        @ApiModelProperty(value = "是否使用积分 0不使用,1使用-WHETHER TO USE POINTS 0 DO NOT USE 1 USE")
        private Integer useScore;
    
        @ApiModelProperty(value = "信用卡信息")
        @SkipBodyParamLogPrint
        private CreditCardInfo creditCardInfo;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    执行方法

    @ApiModelProperty("获取app支付参数")
    @SkipBodyParamLogPrint
    public void getPayOrderToApp(@RequestBody BuyGoodsParam buyGoodsParam) throws IOException {
        orderService.getGoodsOrderFromApp(buyGoodsParam);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    redhat7.6安装weblogic12c
    docker 构建并运行 python项目
    HTML常见标签和作用
    怎么把图片转换成ico图标文件?
    前端关于对象中套用对象传参的小问题
    计算机毕业设计 基于SpringBoot的养老院管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
    Linux 基本指令(上)
    微服务【同步和异步通讯详解】第6章
    【Go】slice
    Mac | 崩溃分析
  • 原文地址:https://blog.csdn.net/m0_49194578/article/details/126089050