在 Java 中的 Jackson JSON 反序列化期间忽略丢失的属性
Posted
技术标签:
【中文标题】在 Java 中的 Jackson JSON 反序列化期间忽略丢失的属性【英文标题】:Ignore missing properties during Jackson JSON deserialization in Java 【发布时间】:2014-01-01 22:48:42 【问题描述】:在示例中
class Person
String name;
int age;
如果 JSON 对象缺少属性“年龄”,
"name": "John"
Person person = objectMapper.readValue(jsonFileReader, Person.class);
它抛出一个JsonMappingException
说它不能反序列化。是否有注解在反序列化过程中忽略缺失的字段?
【问题讨论】:
【参考方案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 数据类(具有构造函数属性)时遇到了这个问题,并且首先找到了 ***.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。以上是关于在 Java 中的 Jackson JSON 反序列化期间忽略丢失的属性的主要内容,如果未能解决你的问题,请参考以下文章
使用 Jackson 将单个文件中的多个 JSON 对象读入 Java
在 Java 中的 Jackson JSON 反序列化期间忽略丢失的属性
将 JSON 子对象属性绑定到 Jackson 中的 Java 对象字段
使用jackson将pojo(对象列表)转换为java中的json