jackson學習之四:WRAP_ROOT_VALUE(root對象)

歡迎訪問個人GitHub

https://github.com/zq2599/blog_demosjava

內容:全部原創文章分類彙總及配套源碼,涉及Java、Docker、Kubernetes、DevOPS等;git

系列文章彙總

本篇概覽

本文是《jackson學習》系列的第四篇,前面學習了經常使用API,能夠執行最基本的序列化和反序列化操做,接下來要學習的就是jackson強大的註解能力,本篇要學的是root對象特性,主要內容以下:程序員

  1. 關於root對象
  2. 測試用的POJO類
  3. 序列化實戰
  4. 反序列化實戰

關於root對象(WRAP_ROOT_VALUE)

  1. 對於只有idname兩個字段的POJO實例來講,正常的序列化結果以下:
{
  "id" : 1,
  "name" : "book"
}
  1. jackson在序列化時,能夠在上述json外面再包裹一層,官方叫作WRAP_ROOT_VALUE,本文中叫作root對象,以下所示,整個json的只有一個鍵值對,key是aaabbbccc,value內部纔是POJO實例的id和name字段的值:
{
  "aaabbbccc" : {
    "id" : 2,
    "name" : "food"
  }
}

提早小結

root對象特性提早作個小結,這樣若是您時間有限,僅看這一節便可:github

  • 先看序列化場景:
  1. 執行下面代碼,jackson在序列化時會增長root對象:
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
  1. root對象的key,默認是實例的類名,若是實例有JsonRootName註解,就是該註解的value值;
  2. root對象的value以下所示,至關於不支持root對象時的序列化結果
{
  "id" : 1,
  "name" : "book"
}
  • 再看反序列化場景:
  1. 執行下面代碼,jackson在反序列化時會先解析root對象:
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
  1. root對象的key,默認是實例的類名,若是實例有JsonRootName註解,就是該註解的value值;
  2. root對象的value以下所示,至關於不支持root對象時用來反序列化的json字符串
{
  "id" : 1,
  "name" : "book"
}

準備兩個POJO類

用對比的方式能夠更清楚瞭解JsonRootName的做用,接下來的學習我們準備兩個POJO類,一個沒有JsonRootName註解,另外一個有JsonRootName註解:web

  1. 名爲Order1.java的,沒有JsonRootName註解:
public class Order1 {
    private int id;
    private String name;
	// 省去get、set、toString方法
	...
}
  1. 名爲Order2.java的,有JsonRootName註解,value值爲aaabbbccc
import com.fasterxml.jackson.annotation.JsonRootName;

@JsonRootName(value = "aaabbbccc")
public class Order2 {
	private int id;
    private String name;
	// 省去get、set、toString方法
	...
}
  • 可見Order1和Order2的代碼是一致的,惟一的不一樣是Order2帶有註解JsonRootName;

序列化

  1. 須要設置WRAP_ROOT_VALUE屬性,jackson纔會支持root對象,JsonRootName註解纔會發揮做用,設置代碼以下:
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
  1. 寫一段代碼,在不開啓WRAP_ROOT_VALUE屬性的時候執行序列化,再開啓WRAP_ROOT_VALUE屬性執行序列化,對比試試:
public static void main(String[] args) throws Exception {
        // 實例化Order1和Order2
        Order1 order1 = new Order1();
        order1. setId(1);
        order1.setName("book");

        Order2 order2 = new Order2();
        order2. setId(2);
        order2.setName("food");

        // 沒有開啓WRAP_ROOT_VALUE的時候
        logger.info("沒有開啓WRAP_ROOT_VALUE\n");
        ObjectMapper mapper1 = new ObjectMapper();
        // 美化輸出
        mapper1.enable(SerializationFeature.INDENT_OUTPUT);

        logger.info("沒有JsonRootName註解類,序列化結果:\n\n{}\n\n", mapper1.writeValueAsString(order1));
        logger.info("有JsonRootName註解的類,序列化結果:\n\n{}\n\n\n\n", mapper1.writeValueAsString(order2));

        // 開啓了WRAP_ROOT_VALUE的時候
        logger.info("開啓了WRAP_ROOT_VALUE\n");
        ObjectMapper mapper2 = new ObjectMapper();
        // 美化輸出
        mapper2.enable(SerializationFeature.INDENT_OUTPUT);
        // 序列化的時候支持JsonRootName註解
        mapper2.enable(SerializationFeature.WRAP_ROOT_VALUE);

        logger.info("沒有JsonRootName註解類,序列化結果:\n\n{}\n\n", mapper2.writeValueAsString(order1));
        logger.info("有JsonRootName註解的類,序列化結果:\n\n{}", mapper2.writeValueAsString(order2));
    }
  1. 執行結果以下,JsonRootName在序列化時的做用一目瞭然:指定了root對象的key:

在這裏插入圖片描述

反序列化(默認設置)

  1. 在沒有作任何設置的時候,下面這個字符串用來反序列化成Order2對象,會成功嗎?
{
  "id" : 2,
  "name" : "food"
}
  1. 試了下是能夠的:

在這裏插入圖片描述
3. 那下面這個字符串能反序列化成Order2對象嗎?spring

{
  "aaabbbccc" : {
    "id" : 2,
    "name" : "food"
  }
}
  1. 代碼和結果以下圖所示,反序列化時jackson並不認識aaabbbccc這個key,由於jackson此時並不支持root對象:

在這裏插入圖片描述

  • 小結:默認狀況下,反序列化時json字符串不能有root對象;

反序列化(開啓UNWRAP_ROOT_VALUE屬性)

  1. 若是開啓了UNWRAP_ROOT_VALUE屬性,用於反序列化的json字符串就必需要有root對象了,開啓UNWRAP_ROOT_VALUE屬性的代碼以下:
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
  1. 代碼和結果以下圖,可見帶有root對象的json字符串,能夠反序列化成功,root對象的key就是JsonRootName註解的value屬性:

在這裏插入圖片描述
3. 值得注意的是,上述json字符串中,root對象的key爲aaabbbccc,這和Order2的JsonRootName註解的value值是一致的,若是不一致就會反序列化失敗,以下圖:數據庫

在這裏插入圖片描述

  • 至此,jackson的WRAP_ROOT_VALUE特性就學習完成了,在web開發時這是個很經常使用的功能,用於在最外面包裹一層,以便總體上添加額外的內容,但願能給您帶來參考;

你不孤單,欣宸原創一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 數據庫+中間件系列
  6. DevOps系列

歡迎關注公衆號:程序員欣宸

微信搜索「程序員欣宸」,我是欣宸,期待與您一同暢遊Java世界...
https://github.com/zq2599/blog_demosjson

相關文章
相關標籤/搜索