java - 特定字段上的自定义 Jackson 序列化程序

标签 java json serialization jackson

我正在寻找基于自定义注释的相同对象的多个 jackson 反序列化器。

理想情况下,我有一个像这样的 POJO:

public class UserInfo {
   @Redacted    
   String ssn;

   String name;
}

在“正常”条件下,我希望这个对象以默认方式序列化:

{"ssn":"123-45-6789", "name":"Bob Smith"}

但出于记录目的(例如)我想编辑 SSN,这样它就不会保存在我们的日志中:

{"ssn":"xxx-xx-xxxx", "name":"Bob Smith"}

我也研究过使用 @JsonSerialize 并提出:

public class UserInfo {

    @JsonSerialize(using = RedactedSerializer.class, as=String.class)
    String firstName;
    String lastName;

}

问题是它总是使用这个规则。是否可以添加多个@JsonSerializer 并在运行时代码中仅使用指定的一个?

我也看到过“ View ”,但理想情况下,我想至少表明请求中存在该字段 - 即使我不知道该值。

最佳答案

100% 安全的方法是在不同的请求中使用不同的 DTO。但是,是的,如果您不能这样做,请使用 @JsonView 和自定义序列化程序,例如:

class Views {
    public static class ShowSSN {}
}

private static class MyBean{
    @JsonSerialize(using = MyBeanSerializer.class)
    @JsonView(Views.ShowSSN.class)
    String ssn;
    //getter setter constructor
}

private class MyBeanSerializer extends JsonSerializer<String> {
    @Override
    public void serialize(String value, JsonGenerator gen,
                          SerializerProvider serializers) throws IOException {
        Class<?> jsonView =  serializers.getActiveView();
        if (jsonView == Views.ShowSSN.class) 
            gen.writeString(value); // your custom serialization code here
        else 
            gen.writeString("xxx-xx-xxxx");
    }
} 

像这样使用它:

public static void main(String[] args) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    MyBean bean = new MyBean("123-45-6789");

    System.out.println(mapper.writerWithView(Views.ShowSSN.class)
                             .writeValueAsString(bean));
    // results in {"ssn":"123-45-6789"}

    System.out.println(mapper.writeValueAsString(bean));
    // results in {"ssn":"xxx-xx-xxxx"}
}

另外比如在 Spring ,它会很容易使用

@Controller
public class MyController {
    @GetMapping("/withView")       // results in {"ssn":"123-45-6789"}
    @JsonView(Views.ShowSSN.class)
    public @ResponseBody MyBean withJsonView() {
        return new MyBean("123-45-6789");
    }

    @GetMapping("/withoutView")    // results in {"ssn":"xxx-xx-xxxx"}
    public @ResponseBody MyBean withoutJsonView() {
        return new MyBean("123-45-6789");
    }

}

关于java - 特定字段上的自定义 Jackson 序列化程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47129953/

相关文章:

c# - 序列化 NodaTime.LocalTime 时的可选秒数?

Java Double 和 Float 数学表现异常

python - 奇怪的 JSON 到 CSV 的转换

javascript - 简单请求: Uncaught TypeError: Cannot read property 'length' of undefined

mysql - qooxdoo 远程请求未完成

java - Kryo 序列化程序在底层 Scala 类 WrappedArray 上导致异常

java - 如何创建带有 Android 事件的 "manager class"?

java - 使用可运行 jar 时未找到 persistence.xml

java - 我尝试将 ExpandableListView 与自定义适配器一起使用,但无法显示任何内容

c++ - 通过 MPI 发送 Lambda 闭包