You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Logging Aspect隐藏日志中特定字段的值?

解决方案:日志中隐藏特定字段值

方法一:直接修改原对象(需注意业务影响)

如果入参允许被修改,可在你代码的注释位置添加字段隐藏逻辑,比如将冗余字段设为null或占位符:

public void beforeAdvice(final JoinPoint joinPoint) {
    final String className = joinPoint.getTarget().getClass().getSimpleName();
    final String methodName = joinPoint.getSignature().getName();
    final List<Object> args = Arrays.asList(joinPoint.getArgs());
    args.stream().forEach(a ->
    {
        if (a.getClass().equals(CreateBlogRequest.class)) {
            ((CreateBlogRequest) a).getSections().stream().forEach(s -> {
              if(s.getSectionType().equals("image")) {
                 // 隐藏image类型的特定字段,比如设为占位符或null
                 s.setImageUrl("[HIDDEN]"); 
                 // 若要移除整个section,需改用迭代器操作(stream中不能直接remove)
              }
            });
        }
    });
    log.info("Invoking: " + className + "." + methodName + " with args:" + args);
}

⚠️ 注意:修改原对象可能影响后续业务逻辑,仅在确认入参无需保留原始值时使用。

方法二:创建对象副本修改(不影响原业务,推荐)

为避免修改原请求对象,可创建副本处理后再输出日志:

import java.util.stream.Collectors;

public void beforeAdvice(final JoinPoint joinPoint) {
    final String className = joinPoint.getTarget().getClass().getSimpleName();
    final String methodName = joinPoint.getSignature().getName();
    final List<Object> args = Arrays.asList(joinPoint.getArgs());

    // 生成用于日志的参数副本,不修改原业务对象
    List<Object> logArgs = args.stream().map(arg -> {
        if (arg.getClass().equals(CreateBlogRequest.class)) {
            CreateBlogRequest originalReq = (CreateBlogRequest) arg;
            // 深拷贝请求对象(复杂对象可使用Jackson序列化/反序列化实现深拷贝)
            CreateBlogRequest logReq = new CreateBlogRequest();
            // 复制其他业务字段
            logReq.setTitle(originalReq.getTitle());
            logReq.setAuthor(originalReq.getAuthor());
            
            // 处理sections列表
            List<Section> logSections = originalReq.getSections().stream().map(section -> {
                Section logSection = new Section();
                logSection.setSectionType(section.getSectionType());
                if (!"image".equals(section.getSectionType())) {
                    // 非image类型保留完整字段
                    logSection.setContent(section.getContent());
                    logSection.setImageUrl(section.getImageUrl());
                } else {
                    // image类型隐藏指定字段
                    logSection.setImageUrl("[HIDDEN]");
                }
                return logSection;
            }).collect(Collectors.toList());
            logReq.setSections(logSections);
            return logReq;
        }
        return arg;
    }).collect(Collectors.toList());

    log.info("Invoking: " + className + "." + methodName + " with args:" + logArgs);
}

方法三:自定义序列化规则(优雅持久化方案)

通过Jackson注解自定义序列化逻辑,无需在切面中编写业务处理代码:

  1. 在Section类中添加自定义序列化器:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;

public class Section {
    private String sectionType;
    private String imageUrl;
    private String content;

    // 为imageUrl字段绑定自定义序列化器
    @JsonSerialize(using = SectionImageUrlSerializer.class)
    public String getImageUrl() {
        return imageUrl;
    }

    // 自定义序列化逻辑
    public static class SectionImageUrlSerializer extends JsonSerializer<String> {
        @Override
        public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            Section currentSection = (Section) gen.getCurrentValue();
            if ("image".equals(currentSection.getSectionType())) {
                gen.writeString("[HIDDEN]");
            } else {
                gen.writeString(value);
            }
        }
    }

    // 其他getter/setter方法
}
  1. 日志输出时使用Jackson序列化对象,自动触发隐藏逻辑:
log.info("Invoking: {} with args: {}", 
         className + "." + methodName, 
         new ObjectMapper().writeValueAsString(logArgs));

内容的提问来源于stack exchange,提问作者Clancinio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 15:45:50