杰克逊前

开始使用Spring 5和Spring Boot 2,通过学习的春天课程:

>>看看这个课程

1.介绍

使用Jackson处理预定义的JSON数据结构非常简单。然而,有时我们需要处理动态JSON对象,它们具有未知的属性

在这篇简短的教程中,我们将看到将动态JSON对象映射到Java类的多种方法。

请注意,在所有测试中,我们都假设有一个字段objectmap类型的com.fasterxml.jackson.databind.ObjectMapper

进一步阅读:

用Jackson映射嵌套值

学习使用Jackson库在Java中反序列化嵌套JSON值的三种方法。

在Jackson中使用Optional

一个关于如何在Jackson中使用Optional的快速概述。

2.使用JsonNode

假设我们想在网店中处理产品规格说明。所有的产品都有一些共同的属性,但也有其他的属性,这取决于产品的类型。

例如,我们想知道手机显示屏的宽高比,但是这个属性对于鞋子来说没有多大意义。

数据结构是这样的:

{"name": "Pear yPhone 72", "category": " phone 72", "details": {"displayAspectRatio": "97:3", "audioConnector": "none"}}

类中存储动态属性细节对象。

我们可以将公共属性映射到以下Java类:

class Product {String name;字符串类;//标准的getter和setter}

最重要的是,我们需要一个合适的表示细节对象。例如,com.fasterxml.jackson.databind.JsonNode可以处理动态键

要使用它,我们必须将它作为一个字段添加到产品类:

类产品{//公共字段JsonNode细节;//标准的getter和setter}

最后,我们验证了它的工作:

String json = "";产品产品= objectMapper。readValue (json, Product.class);为了(product.getName())。isEqualTo(“梨yPhone 72”);为了(product.getDetails () . get (audioConnector) .asText ()) .isEqualTo(“没有”);

然而,我们对这个解决方案有一个问题。我们的类依赖Jackson库,因为我们有JsonNode字段。

3.使用地图

我们可以通过使用解决这个问题java.util.Map细节字段。更准确地说,我们必须使用Map < String,对象>

其他一切都可以保持不变:

class Product {// public fields Map details;//标准的getter和setter}

然后我们可以用一个测试来验证它:

String json = "";产品产品= objectMapper。readValue (json, Product.class);为了(product.getName())。isEqualTo(“梨yPhone 72”);为了(product.getDetails () . get (" audioConnector ")) .isEqualTo(“没有”);

4.使用@JsonAnySetter

当对象只包含动态属性时,前面的解决方案是好的。然而,有时我们有固定属性和动态属性混合在一个JSON对象中

例如,我们可能需要扁平化我们的产品表示:

{"name": "Pear yPhone 72", "category": " phone", "displayAspectRatio": "97:3", "audioConnector": "none"}

我们可以把这样的结构看作是一个动态对象。不幸的是,这意味着我们不能定义公共属性——我们也必须动态地处理它们。

或者,我们可以使用@JsonAnySetter将处理其他未知属性的方法标记为。这样的方法应该接受两个参数:属性的名称和值:

class Product {// public fields Map details = new LinkedHashMap<>();@JsonAnySetter void setDetail(String key, Object value){细节。put(关键字,值);} //标准的getter和setter方法}

注意,我们必须实例化细节对象,以避免nullpointerexception

因为我们将动态属性存储在地图,我们可以像以前一样使用它:

String json = "";产品产品= objectMapper。readValue (json, Product.class);为了(product.getName())。isEqualTo(“梨yPhone 72”);为了(product.getDetails () . get (" audioConnector ")) .isEqualTo(“没有”);

5.创建自定义反序列化器

对于大多数情况,这些解决方案都可以很好地工作。然而,有时我们需要更多的控制。例如,我们可以在数据库中存储关于JSON对象的反序列化信息。金宝搏官网188be

我们可以使用自定义反序列化器针对这些情况。因为这是一个复杂的话题,我们将在另一篇文章中讨论它,开始使用Jackson中的自定义反序列化

6.结论

在本文中,我们看到了使用Jackson处理动态JSON对象的多种方法。

像往常一样,有一些例子在GitHub

杰克逊底部

开始使用Spring 5和Spring Boot 2,通过学习的春天课程:

>>看看这个课程
对这篇文章的评论关闭!