在将DTO字段/秘密转换为json字符串(用于日志(log)记录)时,我需要一种方便的方法来对其进行审查.

我正在使用对象映射器,我听说过大约@JsonProperty(access = JsonProperty.Access.WRITE_ONLY),但它完全隐藏了注释字段,这可能会令人困惑,因为如果我想跟踪日志(log)中的错误,我可能会认为它只是空,因此,如果属性的值简单地替换为类似***的东西,那就更好了.

定义字段名称列表来替换值也不合适,因为我可能会删除我不想删除的字段.此外,重构也会使事情变得复杂.

我的 idea 是使用自定义注释来注释字段,并使用对象映射器实现一些json后处理,但我找不到一种方法来做到这一点. 例如:

public record Person(String name, @Censored String secret) {
}

// and later
log.info(objectMapper.writeValueAsString(person));

输出应

{"name":"John","secret":"***"}

有没有方法将ObjectMapper配置为使用我的自定义@Censored注释注释的字段?

我还愿意接受实施日志(log)审查逻辑的其他建议.

我try 使用@JsonProperty(Access = JsonProperty.Access.WRITE_ONLY),但它没有达到我想要的结果.

推荐答案

我能想到的通过Jackson实现这一点的最简单方法是使用自定义序列化器:

public class CensoredSerializer<T> extends StdSerializer<T> {
    public CensoredSerializer() {
        this(null);
    }

    public CensoredSerializer(Class<T> t) {
        super(t);
    }

    @Override
    public void serialize(T value, JsonGenerator gen, SerializerProvider provider)
            throws IOException
    {
        gen.writeString("***");
    }
}

您会这样使用:

public record Person(String name, @JsonSerialize(using = CensoredSerializer.class) String secret) {
}

如果这对您来说太冗长,您可以将其用作自定义注释的基础:

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = CensoredSerializer.class)
public @interface Censored {
}

这让您可以使用@Censored作为@JsonSerialize(using = CensoredSerializer.class)的缩写,就像这样:

public record Person(String name, @Censored String secret) {
}

正如 comments 中提到的,masking values in the logging config也可以做到这一点.我个人觉得直接在课堂上定义它是有一定价值的,但您的里程可能会有所不同!

Java相关问答推荐

如何在Spring Boot中创建500错误的响应正文?

Java字符串常数池困惑

具有默认分支的JUnit代码覆盖率切换声明

Java应用程序崩溃时试图读取联系人从电话

JUnit—如何模拟局部变量对象方法调用

如何在带有Micronaut的YAML中使用包含特殊字符的字符串作为键

Java Swing:初始化身份验证类后未检测到ATM_Interface键事件

对于几乎不涉及逻辑的请求,您是否应该使用命令模式?

如何找到MongoDB文档并进行本地化?

为什么我的回收视图会显示重复的列表?

try 将JSON字符串响应从API转换为映射字符串、对象>;时出错

删除打印语句会影响功能...腐败在起作用?

当b是一个字节并且在Java中值为-1时,为什么b>;>;>;1总是等于-1?

如何在EL处理器中定义带有命名空间的变量?

何时调用密封层次 struct 的switch 中的默认情况

用于Java的Visual Studio代码完成不起作用

Java CDI:@Singleton@Startup@Inject无法实现接口

如何设置默认序列生成器分配大小

Java泛型方法重载

using case default on switch语句返回;预览特征切换中的模式匹配仅在源级别20及以上的情况下可用;