在本教程中,我们将探索将 Jackson 的原始数据类型JsonNode转换为类型化 Java 集合的不同方法 。虽然我们可以使用JsonNode本身读取 JSON ,但将其转换为 Java 集合可能会很有帮助。 Java 集合提供了优于原始 JSON 数据的优势,例如类型安全、更快的处理以及更多特定于类型的操作的可用性。
设置示例
在我们的代码示例中,我们将了解将 JsonNode转换 为 对象列表 或 映射 的不同方法。让我们设置示例的构建块。
依赖性
首先,我们将 Jackson Core依赖项添加到pom.xml文件中:
<dependency> |
JSON数据
接下来,让我们为我们的用例定义一个 JSON:
{ |
在上面的 JSON 中,我们有一个 JSON 数组people 和一个 JSON 对象 idToPerson。我们将研究将它们转换为 Java 集合的方法。
数据传输对象
让我们定义一个 可以在示例中使用的Person类:
public class Person { |
将 JSON 字符串转换为JsonNode
如果我们想从整个 JSON 中读取一个对象,我们可以使用 Jackson 的ObjectMapper 类来实现:
JsonNode rootNode = new ObjectMapper().readTree(jsonString); |
要将整个 JSON 转换为 JsonNode 对象,我们使用 readTree() 方法。然后,我们 使用 get()方法遍历JsonNode对象,该方法返回具有指定名称的嵌套对象。
手动转换
在检查库方法之前,我们先看一下手动将 JsonNode转换 为集合的方法。
手动将JsonNode转换为列表
要将JsonNode转换为列表,我们可以逐项遍历它并用它创建一个List对象:
List<Person> manualJsonNodeToList(JsonNode personsNode) { |
在这里,我们使用循环来遍历输入节点的所有子节点。仅当我们的输入节点是数组时,这才有可能。
对于每个节点,我们创建一个 Person对象并将其添加到列表中。我们使用get(fieldName)方法从节点 获取姓名和年龄 。 JsonNode 提供了各种方法将返回值转换为原始 Java 类型。这里, asText() 和 asInt()方法 分别 将值转换为 String 和 int 。
手动将JsonNode转换为Map
让我们看一下地图的类似转换:
Map<String, Person> manualJsonNodeToMap(JsonNode idToPersonsNode) { |
在这里,我们使用fields()方法来迭代映射条目。它返回一个 Iterator
使用Jackson的readValue()和convertValue()
Jackson提供了多种方法将 JsonNode转换为Java对象。让我们看一下其中的两个。
1.使用readValue()
readValue () 方法可用于 使用 TypeReference转换为List 或 Map:
List<Person> readValueJsonNodeToList(JsonNode personsNode) throws IOException { |
首先,我们 通过传递需要转换的确切类型来创建一个TypeReference对象。然后我们调用 readValue() 方法,其中 JsonParser由jsonNode.traverse() 提供 。使用解析器,它根据我们提供的TypeReference将节点反序列化为列表或映射 。
2.使用convertValue()
类似地,我们可以使用 convertValue() 方法:
List<Person> convertValueJsonNodeToList(JsonNode personsNode) { |
ConvertValue ()方法的工作原理是首先序列化输入对象,然后将其反序列化为所需的类型。 因此,它可以更灵活地用于从一个对象转换为另一个对象。例如,我们还可以使用它来从 Java 对象到 JsonNode进行反向比较。
自定义解串器
我们还可以提供自定义解串器来执行转换。让我们看看如何定义一个:
public class CustomPersonListDeserializer extends JsonDeserializer<List<Person>> { |
让我们看一下代码中的几个重要部分:
- 首先,该类扩展了 Jackson 的JsonDeserializer。
- 然后,我们重写deserialize()方法并提供我们的实现。
- 在实现中,我们 从 JsonParser对象中获取ObjectMapper 。
- objectMapper.readTree() 将解析器表示的整个树转换为 JsonNode 实例。
- 最后,与手动转换类似,我们 通过循环节点将 JSON 数组中的每个节点转换为Person对象。
解串器的工作方式与其他方法类似,只是它可以提供关注点分离。此外,自定义反序列化器提供了灵活性,因为我们可以在调用代码中轻松地在反序列化器之间切换。