jackson學習之四:WRAP_ROOT_VALUE(root物件)
歡迎訪問我的GitHub
github.com/zq2599/blog_demos
內容:所有原創文章分類彙總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等;
本篇概覽
本文是《jackson學習》系列的第四篇,前面學習了常用API,可以執行最基本的序列化和反序列化操作,接下來要學習的就是jackson強大的註解能力,本篇要學的是root物件特性,主要內容如下:
- 關於root物件
- 測試用的POJO類
- 序列化實戰
- 反序列化實戰
關於root物件(WRAP_ROOT_VALUE)
- 對於只有id和name兩個欄位的POJO例項來說,正常的序列化結果如下:
{
"id" : 1,
"name" : "book"
}
- jackson在序列化時,可以在上述json外面再包裹一層,官方叫做WRAP_ROOT_VALUE,本文中叫做root物件,如下所示,整個json的只有一個鍵值對,key是aaabbbccc,value內部才是POJO例項的id和name欄位的值:
{
"aaabbbccc" : {
"id" : 2,
"name" : "food"
}
}
提前小結
root物件特性提前做個小結,這樣如果您時間有限,僅看這一節即可:
- 先看序列化場景:
- 執行下面程式碼,jackson在序列化時會增加root物件:
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
- root物件的key,預設是例項的類名,如果例項有JsonRootName註解,就是該註解的value值;
- root物件的value如下所示,相當於不支援root物件時的序列化結果:
{
"id" : 1,
"name" : "book"
}
- 再看反序列化場景:
- 執行下面程式碼,jackson在反序列化時會先解析root物件:
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
- root物件的key,預設是例項的類名,如果例項有JsonRootName註解,就是該註解的value值;
- root物件的value如下所示,相當於不支援root物件時用來反序列化的json字串:
{
"id" : 1,
"name" : "book"
}
準備兩個POJO類
用對比的方式可以更清楚瞭解JsonRootName的作用,接下來的學習我們們準備兩個POJO類,一個沒有JsonRootName註解,另一個有JsonRootName註解:
- 名為Order1.java的,沒有JsonRootName註解:
public class Order1 {
private int id;
private String name;
// 省去get、set、toString方法
...
}
- 名為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;
序列化
- 需要設定WRAP_ROOT_VALUE屬性,jackson才會支援root物件,JsonRootName註解才會發揮作用,設定程式碼如下:
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
- 寫一段程式碼,在不開啟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_VALUEn");
ObjectMapper mapper1 = new ObjectMapper();
// 美化輸出
mapper1.enable(SerializationFeature.INDENT_OUTPUT);
logger.info("沒有JsonRootName註解類,序列化結果:nn{}nn", mapper1.writeValueAsString(order1));
logger.info("有JsonRootName註解的類,序列化結果:nn{}nnnn", mapper1.writeValueAsString(order2));
// 開啟了WRAP_ROOT_VALUE的時候
logger.info("開啟了WRAP_ROOT_VALUEn");
ObjectMapper mapper2 = new ObjectMapper();
// 美化輸出
mapper2.enable(SerializationFeature.INDENT_OUTPUT);
// 序列化的時候支援JsonRootName註解
mapper2.enable(SerializationFeature.WRAP_ROOT_VALUE);
logger.info("沒有JsonRootName註解類,序列化結果:nn{}nn", mapper2.writeValueAsString(order1));
logger.info("有JsonRootName註解的類,序列化結果:nn{}", mapper2.writeValueAsString(order2));
}
- 執行結果如下,JsonRootName在序列化時的作用一目瞭然:指定了root物件的key:
反序列化(預設設定)
- 在沒有做任何設定的時候,下面這個字串用來反序列化成Order2物件,會成功嗎?
{
"id" : 2,
"name" : "food"
}
- 試了下是可以的:
3. 那下面這個字串能反序列化成Order2物件嗎?
{
"aaabbbccc" : {
"id" : 2,
"name" : "food"
}
}
- 程式碼和結果如下圖所示,反序列化時jackson並不認識aaabbbccc這個key,因為jackson此時並不支援root物件:
- 小結:預設情況下,反序列化時json字串不能有root物件;
反序列化(開啟UNWRAP_ROOT_VALUE屬性)
- 如果開啟了UNWRAP_ROOT_VALUE屬性,用於反序列化的json字串就必須要有root物件了,開啟UNWRAP_ROOT_VALUE屬性的程式碼如下:
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
- 程式碼和結果如下圖,可見帶有root物件的json字串,可以反序列化成功,root物件的key就是JsonRootName註解的value屬性:
3. 值得注意的是,上述json字串中,root物件的key為aaabbbccc,這和Order2的JsonRootName註解的value值是一致的,如果不一致就會反序列化失敗,如下圖:
- 至此,jackson的WRAP_ROOT_VALUE特性就學習完成了,在web開發時這是個很常用的功能,用於在最外面包裹一層,以便整體上新增額外的內容,希望能給您帶來參考;
我是欣宸,期待與您一同暢遊Java世界…
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2894/viewspace-2797976/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- jackson學習之五:JsonInclude註解JSON
- jackson學習之七:常用Field註解
- jackson學習之八:常用方法註解
- JavaScript學習四(object物件,陣列,)JavaScriptObject物件陣列
- jackson學習之九:springboot整合(配置檔案)Spring Boot
- jackson學習之十(終篇):springboot整合(配置類)Spring Boot
- jackson學習之一:基本資訊
- JavaScript學習4:BOM之window物件JavaScript物件
- JavaScript學習5:BOM之location物件JavaScript物件
- Kafka學習(四)-------- Kafka核心之ProducerKafka
- Kafka學習之(四)PHP操作KafkaKafkaPHP
- jackson學習之三:常用API操作API
- 深入學習js之——變數物件#4JS變數物件
- java學習——物件導向之繼承Java物件繼承
- Java學習筆記之類和物件Java筆記物件
- Elasticsearch聚合學習之四:結果排序Elasticsearch排序
- 機器學習之numpy和matplotlib學習(四)機器學習
- MyBatis學習 之 四、MyBatis配置檔案MyBatis
- Delphi5學習筆記之四筆記
- 使用jackson序列化物件物件
- gRPC學習之四:實戰四類服務方法RPC
- Android學習之四大元件(四)——BroadcastReceiverAndroid元件AST
- Python學習之變數、物件和引用Python變數物件
- Scala 學習筆記(2)之類和物件筆記物件
- tkinter學習系列(四)之Button 控制元件控制元件
- hive學習筆記之四:分割槽表Hive筆記
- 學習Tomcat(四)之Engine和Host容器Tomcat
- InnoDB學習(四)之RedoLog和UndoLog
- ReactNative學習筆記四之動畫篇React筆記動畫
- Python學習四之變數型別Python變數型別
- Java 學習路線之四個階段Java
- java基礎學習之四:修飾符Java
- java中什麼樣的物件才能作為gc root物件,gc root物件有哪些Java物件GC
- JavaScript學習——物件JavaScript物件
- Python 3 學習筆記之——物件導向Python筆記物件
- Python學習之物件導向程式設計Python物件程式設計
- TypeScript 學習(四)TypeScript
- Docker學習-四Docker