1. 程式人生 > >jackson學習之五:JsonInclude註解

jackson學習之五:JsonInclude註解

### 歡迎訪問我的GitHub [https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) 內容:所有原創文章分類彙總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等; ### 系列文章彙總 - [jackson學習之一:基本資訊](https://blog.csdn.net/boling_cavalry/article/details/107135958) - [jackson學習之二:jackson-core](https://blog.csdn.net/boling_cavalry/article/details/108571629) - [jackson學習之三:常用API操作](https://blog.csdn.net/boling_cavalry/article/details/108192174) - [jackson學習之四:WRAP_ROOT_VALUE(root物件)](https://blog.csdn.net/boling_cavalry/article/details/108298858) - [jackson學習之五:JsonInclude註解](https://blog.csdn.net/boling_cavalry/article/details/108412558) - [jackson學習之六:常用類註解](https://blog.csdn.net/boling_cavalry/article/details/108333324) - [jackson學習之七:常用Field註解](https://blog.csdn.net/boling_cavalry/article/details/108589494) - [jackson學習之八:常用方法註解](https://blog.csdn.net/boling_cavalry/article/details/108433330) - [jackson學習之九:springboot整合(配置檔案)](https://blog.csdn.net/boling_cavalry/article/details/108460433) - [jackson學習之十(終篇):springboot整合(配置類)](https://blog.csdn.net/boling_cavalry/article/details/108559056) ### 本篇概覽 1. 本文是《jackson學習》系列第五篇,來熟悉一個常用的註解JsonInclude,該註解的僅在序列化操作時有用,用於控制方法、屬性等是否應該被序列化; 2. 之所以用單獨的一篇來寫JsonInclude註解,是因為該註解的值有多種,每種都有不同效果,最好的學習方法就是編碼實戰; 3. 先對註解的所有取值做個簡介: ```java ALWAYS // 預設策略,任何情況都執行序列化 NON_NULL // 非空 NON_ABSENT // null的不會序列化,但如果型別是AtomicReference,依然會被序列化 NON_EMPTY // null、集合陣列等沒有內容、空字串等,都不會被序列化 NON_DEFAULT // 如果欄位是預設值,就不會被序列化 CUSTOM // 此時要指定valueFilter屬性,該屬性對應一個類,用來自定義判斷被JsonInclude修飾的欄位是否序列化 USE_DEFAULTS // 當JsonInclude在類和屬性上都有時,優先使用屬性上的註解,此時如果在序列化的get方法上使用了JsonInclude,並設定為USE_DEFAULTS,就會使用類註解的設定 ``` ### 原始碼下載 1. 如果您不想編碼,可以在GitHub下載所有原始碼,地址和連結資訊如下表所示(https://github.com/zq2599/blog_demos): | 名稱 | 連結 | 備註| | :-------- | :----| :----| | 專案主頁| https://github.com/zq2599/blog_demos | 該專案在GitHub上的主頁 | | git倉庫地址(https)| https://github.com/zq2599/blog_demos.git | 該專案原始碼的倉庫地址,https協議 | | git倉庫地址(ssh)| [email protected]:zq2599/blog_demos.git | 該專案原始碼的倉庫地址,ssh協議 | 2. 這個git專案中有多個資料夾,本章的應用在jacksondemo資料夾下,如下圖紅框所示: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202102/485422-20210202084750110-860547581.png) 3. jacksondemo是父子結構的工程,本篇的程式碼在annotation子工程中,裡面的jsoninclude這個package下,如下圖: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202102/485422-20210202084751176-1515316689.jpg) - 接下來逐個學習這些屬性的效果; ### ALWAYS ALWAYS表示全部序列化,如下圖,null和空字串都會序列化: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202102/485422-20210202084752437-1331382705.jpg) ### NON_NULL NON_NULL好理解,就是值為null就不序列化: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202102/485422-20210202084754051-751441111.jpg) ### NON_ABSENT 1. NON_ABSENT略為複雜,當例項化的物件有Optional或AtomicReference型別的成員變數時,如果Optional引用的例項為空,用NON_ABSENT能使該欄位不做序列化; 2. Optional是java用來優雅處理空指標的一個特性,本文中不做過多說明,請您自行查閱相關文件; 3. 要讓Jackson支援Optional特性,必須做兩件事,首先是在pom.xml中新增以下依賴: ```xml ``` 4. 其次是程式碼中執行以下設定: ```java mapper.registerModule(new Jdk8Module()); ``` 5. 咱們先看看設定成NON_NULL時jackson對Optional和AtomicReference的處理,下面的程式碼中,Optional和AtomicReference的引用都是空,但還是被序列化出來了: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202102/485422-20210202084756348-1723841510.jpg) 6. 程式碼不變,將NON_NULL改為NON_ABSENT試試,如下圖,可見field2和field3都沒有序列化了: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202102/485422-20210202084758168-704887738.jpg) 小結NON_ABSENT的效果: a. 自身為null的欄位不會被序列化; b. Optional型別的欄位,如果引用值為null,該欄位不會被序列化; c. AtomicReference型別的欄位,如果引用值為null,該欄位不會被序列化; ### NON_EMPTY NON_EMPTY好理解,以下情況都不會被序列化: 1. null 2. 空字串 3. 空集合 4. 空陣列 5. Optional型別的,其引用為空 6. AtomicReference型別的,其引用為空 7. 演示程式碼和結果如下圖,可見上述場景全部沒有被序列化: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202102/485422-20210202084759399-674461517.jpg) ### NON_DEFAULT 1. 設定為NON_DEFAULT後,對保持預設值的欄位不做序列化,如下圖: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202102/485422-20210202084800585-94725648.jpg) ### CUSTOM 1. 相對其他型別,CUSTOM略為複雜,這個值要配合valueFilter屬性一起使用; 2. 如下所示,JsonInclude的value等於CUSTOM時,在序列化的時候會執行CustomFilter的equals方法,該方法的入參就是field0的值,如果equals方法返回true,field0就不會被序列化,如果equals方法返回false時field0才會被序列化 ```java @JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = CustomFilter.class) private String field0; ``` 3. 來看看CustomFilter類的程式碼,如下所示,只有equals方法,可見:null、非字串、長度大於2這三種情況都返回true,也就是說這三種情況下都不會被序列化: ```java static class CustomFilter { @Override public boolean equals(Object obj) { // null,或者不是字串就返回true,意味著不被序列化 if(null==obj || !(obj instanceof String)) { return true; } // 長度大於2就返回true,意味著不被序列化 return ((String) obj).length() > 2; } } ``` 4. 下面貼出完整程式碼和結果,您就一目瞭然了: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202102/485422-20210202084802576-1778550824.jpg) - 再次強調:valueFilter的equals方法返回true,意味著該欄位不會被序列化!!! ### USE_DEFAULTS USE_DEFAULTS的用法也有點繞,咱們通過對比的方法來學習; 1. 程式碼如下所示,在類和成員變數上都有JsonInclude註解,序列化field0的時候,是哪個註解生效呢?: ```java @JsonInclude(JsonInclude.Include.NON_EMPTY) static class Test { @JsonInclude(JsonInclude.Include.NON_NULL) private List