JSON處理不再頭疼!Jackson Tree模型解鎖JSON操作的開掛模式
環(huán)境:SpringBoot3.4.2
1. 簡介
Jackson是一個強(qiáng)大的Java庫,用于處理JSON數(shù)據(jù)。JsonNode是Jackson庫中的一個核心類,它允許你以樹模型的方式處理JSON數(shù)據(jù)。
本篇文章將重點介紹如何在Jackson中使用樹模型節(jié)點,我們將使用JsonNode進(jìn)行各種轉(zhuǎn)換,以及添加、修改和刪除節(jié)點。
2.實戰(zhàn)案例
2.1 創(chuàng)建節(jié)點
首先,我們創(chuàng)建ObjectMapper對象,接下來的所有操作都將通過該對象完成。
ObjectMapper mapper = new ObjectMapper();如果你是在Spring Boot環(huán)境,那么你可以直接注入該對象,如下示例:
@Service
public class JsonService {
  private final ObjectMapper mapper ;
  public JsonService(ObjectMapper mapepr) {
    this.mapper = mapper ;
  }
  // TODO
}在基于Spring Boot環(huán)境下,相關(guān)jackson的配置你可以直接通過配置文件完成,無需自己編碼進(jìn)行設(shè)置。
- 創(chuàng)建新節(jié)點
 
我們可以通過如下兩種方式創(chuàng)建節(jié)點:
JsonNode node = mapper.createObjectNode();或者通過如下工廠類創(chuàng)建
JsonNode node = JsonNodeFactory.instance.objectNode();- 從JSON字符串解析
 
String jsonStr = """
      {"title":"Spring Boot3實戰(zhàn)案例200講","author":"Pack_xg"}
    """ ;
JsonNode node = mapper.readTree(jsonStr);如果你需要使用比這更低級的功能,那么你可以使用JsonParser
JsonFactory factory = mapper.getFactory();
JsonParser parser = factory.createParser(jsonStr);
JsonNode node = mapper.readTree(parser) ;- 從Java對象轉(zhuǎn)換
 
可以通過ObjectMapper#valueToTree方法從Java對象轉(zhuǎn)換而來:
User user = new User(1L, "Pack_xg") ;
JsonNode node = mapper.valueToTree(user);或者通過如下方法
JsonNode node = mapper.convertValue(user, JsonNode.class);如下完成的示例:
User user = new User(1L, "Pack_xg") ;
JsonNode node = mapper.convertValue(user, JsonNode.class);
Long id = node.get("id").asLong() ;
String name = node.get("name").asText() ;
System.err.printf("id = %d, name = %s%n", id, name) ;輸出結(jié)果
id = 1, name = Pack_xg2.2 轉(zhuǎn)換節(jié)點
- 轉(zhuǎn)換為JSON字符串
 
ObjectMapper mapper = new ObjectMapper() ;
User user = new User(1L, "Pack_xg") ;
mapper.writeValue(System.out, user) ;輸出結(jié)果
{"id":1,"name":"Pack_xg"}ObjectMapper#writeValue有幾個重載的方法,如下:
圖片
- 轉(zhuǎn)換為Java對象
 
將JsonNode轉(zhuǎn)換為Java對象最方便的方法是treeToValue方法:
JsonNode node = ... ;
Book value = mapper.treeToValue(node, Book.class);或者通過如下Token Stream方式轉(zhuǎn)換
JsonParser parser = mapper.treeAsTokens(node);
Book value = mapper.readValue(parser, Book.class);如下完整示例:
JsonNode node = mapper.createObjectNode();
ObjectNode objectNode = (ObjectNode) node;
objectNode.put("title", "Spring全家桶實戰(zhàn)案例");
objectNode.put("author", "pack");
Book book = mapper.treeToValue(node, Book.class);
System.err.println(book) ;輸出結(jié)果
Book [title=Spring全家桶實戰(zhàn)案例, author=pack]2.3 操作樹節(jié)點
首先,我們準(zhǔn)備如下的data.json文件:
{
  "user": {
    "firstName": "pack",
    "lastName": "xg"
  },
  "title": "Spring Boot3實戰(zhàn)案例200講",
  "company": "XXXOOO科技公司"
}其次,我們獲取該json文件的根節(jié)點:
ObjectMapper mapper = new ObjectMapper() ;
ClassPathResource resource = new ClassPathResource("data.json") ;
InputStream is = resource.getInputStream() ;
JsonNode rootNode = mapper.readTree(is);接下來,我們的操作都將基于該rootNode進(jìn)行。
- 定位節(jié)點
 
如果我們事先知道節(jié)點的路徑,那就很容易進(jìn)行節(jié)點的定位。如下定義firstName節(jié)點:
JsonNode firstName = rootNode.path("user").path("firstName");
// 輸出: pack
System.err.println(firstName.asText()) ;或者也可以通過get或withObject/get方法獲取對應(yīng)的節(jié)點:
firstName = rootNode.get("user").get("firstName") ;
System.err.println(firstName.asText()) ;
firstName= rootNode.withObject("user").get("firstName") ;
System.err.println(firstName.asText()) ;我們還可以通過路徑方式訪問節(jié)點,如下示例:
String lastName = rootNode.at("/user/lastName").asText();
System.err.println(lastName) ;通過at方法,參數(shù)為/xx/yy/zz,注意必須是 "/" 開頭,如果對應(yīng)的階段不存在,則返回空(非null)。
- 添加新節(jié)點
 
我們可以通過ObjectNode#put方法動態(tài)添加節(jié)點,如下示例:
ObjectNode newNode = ((ObjectNode) rootNode).put("price", new BigDecimal("70")) ;
System.err.println(newNode.toPrettyString()) ;輸出結(jié)果
{
  "user" : {
    "firstName" : "pack",
    "lastName" : "xg"
  },
  "title" : "Spring Boot3實戰(zhàn)案例200講",
  "company" : "XXXOOO科技公司",
  "price" : 70
}- 編輯節(jié)點
 
可以通過調(diào)用set(String fieldName, JsonNode value)方法來修改ObjectNode實例,如下示例:
ObjectNode objectNode = (ObjectNode) rootNode ;
TextNode textNode = mapper.createObjectNode().textNode("數(shù)字化創(chuàng)新科技公司") ;
JsonNode ret = objectNode.set("company", textNode);
System.err.println(ret.toPrettyString()) ;輸出結(jié)果
圖片
- 刪除節(jié)點
 
可以通過ObjectNode#remove方法刪除指定的節(jié)點,如下示例:
JsonNode userNode = rootNode.get("user") ;
ObjectNode objectNode = (ObjectNode) userNode ;
objectNode.remove("firstName") ;
System.err.println(rootNode.toPrettyString()) ;輸出結(jié)果
圖片















 
 
 









 
 
 
 