【问题标题】:Ignore missing properties during Jackson JSON deserialization in Java在 Java 中的 Jackson JSON 反序列化期间忽略丢失的属性
【发布时间】:2014-01-01 22:48:42
【问题描述】:

在示例中

class Person {
   String name;
   int age;
}

如果 JSON 对象缺少属性“年龄”,

{
    "name": "John"
}
Person person = objectMapper.readValue(jsonFileReader, Person.class);

它抛出一个JsonMappingException 说它不能反序列化。是否有注解在反序列化过程中忽略缺失的字段?

【问题讨论】:

    标签: java json serialization jackson


    【解决方案1】:

    如果您使用 @JsonProperty(access = JsonProperty.Access.READ_ONLY) 注释年龄,它将仅在反序列化期间被忽略。

    【讨论】:

      【解决方案2】:

      您还可以更改您的类以使用整数而不是整数,在这种情况下,Jackson 将正确处理 null/缺失的“年龄”值。只需为那些寻找不涉及使用注释的替代方案的人添加此答案即可。

      class Person {
         String name;
         Integer age;
      }
      

      【讨论】:

        【解决方案3】:

        @JsonIgnoreProperties(ignoreUnknown = true) 在课堂上为我工作。

        【讨论】:

        • 这是有效的,但在更高的级别。请小心,因为它可以防止系统在“不匹配” json 参数的情况下触发异常。
        • 这不是问题的答案。 JsonIgnoreProperties(ignoreUnknown = true) 仅在传入的 JSON 消息包含的属性多于您尝试序列化的对象时才有用。
        • @TamasG.that 可能是此注释的目的,但不能否认它确实可以解决问题(至少从 Jackson 2.1.1 开始)。
        【解决方案4】:

        Jackson 库的现代版本 (2.9.6) 默认会忽略缺少的创建者属性。但是,如果 ObjectMapper 配置设置为:

        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES, true);
        

        如果缺少其中一个属性,您将收到反序列化错误。

        【讨论】:

        • 这是为我解决问题的答案。 Jackson 将缺失的原始属性反序列化为 0/false 的默认行为简直太疯狂了,它应该是选择加入而不是选择退出。我在尝试将 JSON 数字反序列化为 Kotlin 数据类(具有构造函数属性)时遇到了这个问题,并且首先找到了 stackoverflow.com/questions/14434679
        • 查看DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES 的Javadoc,这似乎是自Jackson 2.6 以来的行为,即自2015 年7 月以来。
        【解决方案5】:

        基于注释的方法是忽略但如果需要的更好方法。手动反序列化方式:

        ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        Person       person = mapper.readValue(jsonFileReader, Person.class);
        

        【讨论】:

        • 您介意解释一下为什么基于注释的方法比“手动方式”更好吗?
        • @jayeffkay 通常只关注 Pojo 而不是反序列化逻辑是首选方式。您可以将其视为手动创建 JDBC 连接与 ORM 实体。但是,如果您想要自定义解决方案。欢迎使用手动方式。
        • 我认为当遗留代码无法更改时,手动方式很有用。例如,实现 E2E 测试,其中序列化/反序列化是处理对象的主要部分,但代码本身不能更改。
        • 使用注解好还是逻辑好,视情况而定。通过将注释放在 pojo 上,它将 pojo 与底层序列化机制联系起来,这在某些情况下是不可取的。请注意,“plain old Java object”这个名称本身意味着该对象是一个“plain”对象,而不是与特定技术相关的对象(当然,Java 除外!)
        【解决方案6】:

        我想你想要的是

        @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
        public class Person {
          ...
        }
        

        这就是 Jackson 1.x 的方式。我认为 2.x 中有一种新方法。类似的东西

        @JsonInclude(Include.NON_NULL)
        public class Person {
          ...
        }
        

        这些将告诉 Jackson 仅序列化不为 null 的值,并且在反序列化缺失值时不要抱怨。我认为它只会将其设置为 Java 默认值。

        【讨论】:

        • @JsonInclude 在序列化对象时产生效果,但这个问题是关于反序列化 JSON。
        猜你喜欢
        • 2014-06-13
        • 1970-01-01
        • 2015-09-04
        • 1970-01-01
        • 2013-08-17
        • 2012-12-09
        • 2012-02-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多