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

如何在Java DTO中对自定义注解字段进行日志脱敏?

日志敏感字段脱敏实现方案

基于Jackson自定义注解的脱敏方案

步骤1:定义自定义脱敏注解

创建@Censored注解,标记需要脱敏的字段:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Censored {
}

步骤2:实现Jackson上下文序列化器

编写序列化器,识别带@Censored注解的字段并替换为***:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;

import java.io.IOException;

public class CensoredSerializer extends JsonSerializer<Object> implements ContextualSerializer {

    private boolean needCensor;

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (needCensor) {
            gen.writeString("***");
        } else {
            gen.writeObject(value);
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
        Censored annotation = property.getAnnotation(Censored.class);
        this.needCensor = annotation != null;
        return this;
    }
}

步骤3:配置ObjectMapper注册序列化器

创建全局ObjectMapper实例,将自定义序列化器注册进去:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;

public class ObjectMapperConfig {
    public static ObjectMapper getCensoredObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addSerializer(Object.class, new CensoredSerializer());
        objectMapper.registerModule(module);
        return objectMapper;
    }
}

步骤4:使用示例

在DTO字段上添加@Censored注解,序列化时自动脱敏:

public class Person {
    private String name;
    
    @Censored
    private String secret;

    // 构造器、getter、setter省略
}

// 测试序列化
public class CensorTest {
    public static void main(String[] args) throws Exception {
        Person person = new Person("Alice", "my-secret-123");
        ObjectMapper mapper = ObjectMapperConfig.getCensoredObjectMapper();
        String json = mapper.writeValueAsString(person);
        // 输出结果: {"name":"Alice","secret":"***"}
        System.out.println(json);
    }
}

其他日志脱敏实现方案

  • 日志框架自定义转换器:以Logback为例,实现Converter接口,在convert方法中匹配日志内容里的敏感字段(如手机号、密码)并替换为脱敏字符,然后在配置文件中指定使用该转换器处理日志消息。
  • AOP切面拦截:利用Spring AOP或AspectJ,拦截日志输出方法(如Logger.debug()/info()),对方法参数中的DTO对象进行脱敏处理——复制对象后替换敏感字段值,再传递给日志方法输出。
  • 第三方脱敏工具库:使用现成的脱敏组件,通过注解或配置规则快速实现字段脱敏,无需手动编写序列化逻辑。
  • DTO复制脱敏:日志输出前手动复制DTO对象,将敏感字段值替换为***后再序列化输出。这种方式简单直接,但需要维护复制逻辑,适合小范围场景。

内容的提问来源于stack exchange,提问作者Baksa Zoltán

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:52:34