杰克逊 - 必需的财产?

Posted

技术标签:

【中文标题】杰克逊 - 必需的财产?【英文标题】:Jackson - Required property? 【发布时间】:2013-07-13 17:59:19 【问题描述】:

我在对象映射器上使用 Jackson 的 readValue() 方法从 JSON 文件中读取并将其转换为我的 java 对象。

例如。

mapperObject.readValue( node, MyTargetClass.class )

我可以在 MyTargetClass 上设置任何注释来强制执行所需的属性吗?例如,如果我有一个带有属性 ABC、DEF 和 GHI 的 JSON 对象,而我的 Json 如下


  "ABC" : "somevalue"
  "DEF" : "someothervalue" 

我希望它以某种方式失败,并且只有在 readValue 包含 ABC、DEF 和 GHI 时才能成功。

【问题讨论】:

【参考方案1】:

Jackson 不包含验证功能,这是设计使然(即被视为超出范围)。但通常使用的是Bean Validation API 实现。 这样做的好处是数据格式处理和验证逻辑之间的解耦。 这就是 DropWizard 之类的框架所使用的;这是 JAX-RS(如 Jersey)为 JAX-RS 2.0 开发的方向。

【讨论】:

请问您如何使用Bean Validation APIreadValue() 的任何示例? 第一个热门的谷歌搜索“带有 bean 验证的杰克逊验证”? baeldung.com/javax-validation -- 不在readValue() 内,首先你阅读(绑定),然后验证。 谢谢,经过几个小时的搜索,我最终也结束了该链接。我的第一个谷歌点击是这个答案。【参考方案2】:

您可以使用@JsonProperty(required = true)注解将属性标记为需要,如果该属性丢失或为空,它将在反序列化过程中抛出JsonMappingException。

编辑:我收到了对此的反对票,没有发表评论。我很想知道为什么,因为它完全正确。

【讨论】:

你好。也许是因为它还没有工作。见:***.com/questions/18320731/… @GunithDevasurendra 它在 Jackson 的最新版本中确实有效。 我使用的是 2.7.3,它可以工作。但是,我发现了一种情况:使用 @JsonDeserialize(builder = Foo.Builder.class) 时注释构建器方法。 我正在使用 spring boot 1.5.9.RELEASE,它使用 jackson-core 2.8.10 和 jackson-annotations 2.8.0,但它似乎不起作用 我检查了 2.8.0 的源代码,它的 javadoc 说“请注意,从 2.6 开始,此属性仅用于 Creator 属性,以确保 JSON 中存在属性值:对于其他属性 (使用 setter 或可变字段注入的),不执行验证。将来可能会添加对这些情况的支持。此属性的状态通过自省公开,其值通常由 Schema 生成器使用,例如用于 JSON Schema 。”【参考方案3】:

如果要确保提供了 json 字段,则必须使用 @JsonProperty(value = "fieldName", required = true) 注释作为构造函数的参数。但这还不够,构造函数还应该有@JsonCreator 注释。

例如,如果您有一个名为“endPoint”的字段,并且您想确保它在 JSON 文件中提供,那么如果未提供,以下代码将引发异常。

@JsonCreator
public QuerySettings(@JsonProperty(value = "endPoint", required = true) String endPoint) 
        this.endPoint = endPoint;

我发现this link 有助于理解 Jackson 注释。它也很好地解释了为什么 required=true 是不够的,而且它的名字有悖于直觉。

【讨论】:

仅供参考,我发现 @JsonCreator 对于版本 2.9.10.3 来说不是必需的。 这对我有用,谢谢;它也适用于数据类定义【参考方案4】:

如果您对使用 @JsonProperty(required = true) 既不满意,因为它仅适用于 @JsonCreator,也不使用 bean 验证,那么另一种解决方法是在相关变量的 setter 方法中捕获它。

您可以在设置变量之前简单地检查变量是否为空,然后抛出IllegalArgumentExceptionNullPointerException(少数人喜欢)

注意:这也取决于您的 POJO 是如何定义的,因此请确保它正在使用 setter 方法路由以使该解决方案起作用。

【讨论】:

以上是关于杰克逊 - 必需的财产?的主要内容,如果未能解决你的问题,请参考以下文章

杰克逊的@JsonSubTypes仍然是多态反序列化所必需的吗?

消防工程必需知道的消防系统监控范围和功能

一文了解做消防工程必需知道的消防系统监控范围和功能

GhostDoc如何获取属性的属性?

迈克尔·杰克逊的死因

迈科尔·杰克逊介绍