Jackson中Json Node的相互转换

2,812 阅读3分钟

「这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战」。

作者:汤圆

个人博客:javalover.cc

前言

我们前文介绍的Jackson比较两个Json对象 - 掘金 (juejin.cn)中,有用到JsonNode;

本篇我们就来介绍下构建JsonNode的相关知识;

目录

  1. JsonNode类关系图
  2. 构建空的Json Node
  3. 构建非空的Json Node
  4. Json Node转为Java对象

正文

1. JsonNode类关系图

这里先看下JsonNode的一个简单类关系图,图里面的一些类做了删减;

image-20220219125735266

JsonNode有多个子类,包括ArrayNode,ObjectNode,ValueNode等;

  • ArrayNode用来表示Json对象中的数组;
  • ObjectNode用来表示Json对象中的普通对象;
  • ValueNode用来表示Json对象中的基本类型,比如int, boolean等;

2. 构建空的Json Node

这种方式很简单,就是直接创建,我们可以通过ObjectMapper创建,也可以通过JsonNodeFactory工厂创建;

a. 先通过ObjectMapper创建,代码如下:

ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.createObjectNode();

这里的createObjectNode实际返回的是一个ObjectNode对象,因为该对象是JsonNode的子类,所以可以自动转换;

b. 再通过JsonNodeFactory工厂方式创建,代码如下:

JsonNode jsonNode2 = JsonNodeFactory.instance.objectNode();

工厂方式不需要创建ObjectMapper,就可以直接创建,很方便;

3. 构造非空的Json Node

这种方式就是从现有的数据进行解析;

前面我们接触过一些,比如readTree,就是将Json字符串解析为Json对象;

下面我们再详细点,多介绍几种,这样我们以后用的话知道有这个东西,可以知道去哪里查(去Jackson官网查);

a. 从Json字符串解析

假设有下面的Json字符串:

String s = "{\"name\":\"jalon\"}";

那我们可以直接通过readTree解析:

JsonNode jsonNode1 = objectMapper.readTree(s);
System.out.println(jsonNode1);

此时输出:{"name":"jalon"}

b. 从Java对象解析

我们还可以直接将一个Java对象解析为Json Node对象;

假设有一个User类,如下所示:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private String username;

    private String nickname;

}

我们可以通过valueToTree方法,直接将User对象转为Json Node对象,如下所示:

User user = new User("jalon", "ming");
JsonNode jsonNode3 = objectMapper.valueToTree(user);
System.out.println(jsonNode3);

此时输出:{"username":"jalon","nickname":"ming"}

4. JsonNode转为Java对象

上面我们介绍了几种构造Json Node的方法,下面介绍下如何来使用Json Node转为Java对象;

Json Node转Java对象也是有多种方式:

a. 方法treeToValue:

这种方法刚好跟上面的Java对象转Json Node相反(valueToTree),方法为treeToValue(),如下所示:

User user1 = objectMapper.treeToValue(jsonNode3, User.class);
System.out.println(user1);

此时输出为一个User对象:User(username=jalon, nickname=ming)

b. 方法convertValue:

跟上面的转换效果一样,代码如下:

User user2 = objectMapper.convertValue(jsonNode3, User.class);
System.out.println(user2);

此时输出也是一个user对象:User(username=jalon, nickname=ming)

不同的是,这个方法可以接受的第一个参数是普通的Object对象,范围很广,而上面的treeToValue只能接受Json Node这样的节点对象;

c. 通过JsonParser间接转换:

这种方式会比较麻烦一点,需要先将Json Node对象转为JsonParser,然后再从JsonParser中读取对象的数据;

如下所示:

JsonParser jsonParser = objectMapper.treeAsTokens(jsonNode3);
User user3 = objectMapper.readValue(jsonParser, User.class);
System.out.println(user3);

JsonParser是用来解析Json数据的,它和ObjectMapper的功能有点类似,只是ObjectMapper用的比较多,因为Jsonparser比较偏底层,会复杂一点;

总结

本篇主要介绍了Json Node的构造以及如何转为Java对象,下面我们把上面涉及到的方法再总结一下;

  1. 构造空的Json Node的方法:
  • objectMapper.createObjectNode();
  • JsonNodeFactory.instance.objectNode();
  1. 构造非空的Json Node的方法:
  • objectMapper.readTree(s);

  • objectMapper.valueToTree(user);

  1. Json Node转Java对象:
  • objectMapper.treeToValue(jsonNode, User.class);

  • objectMapper.convertValue(jsonNode, User.class);