【问题标题】:How to deserialize null type JSON fields with Jackson如何使用 Jackson 反序列化空类型 JSON 字段
【发布时间】:2019-09-12 17:29:35
【问题描述】:

我正在开发一个 PATCH API。如果字段以JSONnull 值发送,我需要将它们保存为null。但是我无法区分它们是作为null 发送还是从不发送。

{
      "max_amount": null
}
Double maxAmount;

我有DoubleIntegerDate 等字段。当它们真正以null 发送时,我可以将它们反序列化为Double.NANInteger.MIN_VALUE,以了解它们是否以null 发送。但是当字段为null 时,反序列化程序不起作用。当然,可以选择发送“-1”或定义null 的不可能值,但我不喜欢这种方法。我必须同意所有类型的客户。在这种情况下,最好的方法是什么?

【问题讨论】:

    标签: java json null jackson deserialization


    【解决方案1】:

    在这种情况下,您应该定义 POJO 类,并将属性设置为预定义的 undefined like 数据。例如,对于Integer 属性,如果从业务角度来看不允许负数,则它可能是-1。然后,当JSON 反序列化为POJO 属性设置为null 覆盖默认值,你会知道它已发送。应该有3个选项:

    1. JSON 中的常规值 - 正确反序列化为 POJO 中的值
    2. null JSON 中的值 - 反序列化为 POJO 中的 null
    3. 不可用的对 key-value - POJO 中的默认值未被覆盖。

    以下示例在版本2.9.9 中使用Jackson

    import com.fasterxml.jackson.annotation.JsonFormat;
    import com.fasterxml.jackson.annotation.JsonProperty;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
    
    import java.time.LocalDateTime;
    
    public class JsonApp {
    
        public static void main(String[] args) throws Exception {
            ObjectMapper mapper = new ObjectMapper();
            mapper.registerModule(new JavaTimeModule());
    
            String[] jsons = {
                    "{\"number\":1,\"date\":\"2019-01-01T22:23:11\",\"max_amount\":4.9}",
                    "{\"number\":null,\"date\":null,\"max_amount\":null}",
                    "{}",
                    "{\"number\":1}",
                    "{\"date\":\"2019-01-01T22:23:11\"}",
                    "{\"max_amount\":4.9}",
                    "{\"number\":1,\"date\":null,\"max_amount\":null}"
            };
            for (String json : jsons) {
                System.out.println(json + " => " + mapper.readValue(json, Pojo.class));
            }
        }
    }
    
    class Pojo {
    
        private static final LocalDateTime NULL_DATE = LocalDateTime.of(1900, 1, 1, 12, 13);
    
        @JsonProperty("max_amount")
        private Double maxAmount = Double.MIN_VALUE;
        private Integer number = Integer.MIN_VALUE;
    
        @JsonFormat(shape = JsonFormat.Shape.STRING)
        private LocalDateTime date = NULL_DATE;
    
        public Double getMaxAmount() {
            return maxAmount;
        }
    
        public void setMaxAmount(Double maxAmount) {
            this.maxAmount = maxAmount;
        }
    
        public Integer getNumber() {
            return number;
        }
    
        public void setNumber(Integer number) {
            this.number = number;
        }
    
        public LocalDateTime getDate() {
            return date;
        }
    
        public void setDate(LocalDateTime date) {
            this.date = date;
        }
    
        @Override
        public String toString() {
            return "{" +
                    "number=" + number +
                    ", date=" + date +
                    ", maxAmount=" + maxAmount +
                    '}';
        }
    }
    

    上面的代码打印:

    {"number":1,"date":"2019-01-01T22:23:11","max_amount":4.9} => {number=1, date=2019-01-01T22:23:11, maxAmount=4.9}
    {"number":null,"date":null,"max_amount":null} => {number=null, date=null, maxAmount=null}
    {} => {number=-2147483648, date=1900-01-01T12:13, maxAmount=4.9E-324}
    {"number":1} => {number=1, date=1900-01-01T12:13, maxAmount=4.9E-324}
    {"date":"2019-01-01T22:23:11"} => {number=-2147483648, date=2019-01-01T22:23:11, maxAmount=4.9E-324}
    {"max_amount":4.9} => {number=-2147483648, date=1900-01-01T12:13, maxAmount=4.9}
    {"number":1,"date":null,"max_amount":null} => {number=1, date=null, maxAmount=null}
    

    当然,您应该选择默认值,这样可以最大限度地减少客户端意外发送被您的API 视为undefined 的值的可能性。

    【讨论】:

    • 感谢您的评论和努力。然而,我们找到了一个更好的解决方案来摆脱默认值。我们定义了一个 isMaxAmountSet 布尔值,并在 maxAmount 的设置器中将其设置为 true。所以,我们可以区分这个值是否在请求体中发送。
    猜你喜欢
    • 2016-07-26
    • 2017-12-23
    • 2017-09-08
    • 2018-07-21
    • 1970-01-01
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多