Jaskson精講第7篇-類繼承關係下的JSON序列化與反序列化JsonTypeInfo

2021-01-08 紙鶴視界

Jackson是Spring Boot(SpringBoot)默認的JSON數據處理框架,但是其並不依賴於任何的Spring 庫。有的小夥伴以為Jackson只能在Spring框架內使用,其實不是的,沒有這種限制。它提供了很多的JSON數據處理方法、註解,也包括流式API、樹模型、數據綁定,以及複雜數據類型轉換等功能。它雖然簡單易用,但絕對不是小玩具,更多的內容我會寫成一個系列,5-10篇文章,請您繼續關注我。

《序列化與反序列化核心用法-JSON框架Jackson精解第1篇》《特殊數據格式處理-JSON框架Jackson精解第2篇》《屬性序列化自定義排序與字母表排序-JSON框架Jackson精解第3篇》《@JacksonInject與@JsonAlias註解-JSON框架Jackson精解第4篇》《@JsonCreator自定義反序列化函數-JSON框架Jackson精解第5篇》《Jaskson精講第6篇-自定義JsonSerialize與Deserialize實現數據類型轉換》本篇文章是系列文章的第7篇,主要是為大家介紹一下,在Java 類繼承的情況下如何實現父類及子類的JSON序列化與反序列化。

一、繼承關係對象構建

首先構建一個ClsShape類表示形狀。

public class ClsShape {}構建一個ClsCircle 類表示圓形。並添加了一系列的lombok註解,Data表示提供get、set、toString、hashCode等方法;EqualsAndHashCode註解在有繼承關係的字類中使用;AllArgsConstructor和NoArgsConstructor分別提供全參和無參構造方法。

@Data@EqualsAndHashCode(callSuper = true)@AllArgsConstructor@NoArgsConstructorpublic class ClsCircle extends ClsShape { Integer radius; //弧度}構建一個長方形類ClsRectangle ,成員變量width寬度,height高度。

@Data@EqualsAndHashCode(callSuper = true)@AllArgsConstructor@NoArgsConstructorpublic class ClsRectangle extends ClsShape { private Integer width; private Integer height;}構建一個ClsView類,表示畫面。畫面中有很多的ClsShape形狀,所以用一個List封裝。

@Datapublic class ClsView { private List<ClsShape> shapes;}二、序列化與反序列化測試

基礎的形狀類及畫面類寫完之後,下面的代碼是用來完成:對象到Json字符串的序列化過程,和Json字符串反序列化為Java對象的過程代碼。

@Testvoid testJSON2Object() throws IOException { ClsRectangle rectangle = new ClsRectangle(7,9); //構建正方形對象 ClsCircle circle = new ClsCircle(8); //構建長方形對象 List<ClsShape> shapes = new ArrayList<>(); //List<多種形狀> shapes.add(circle); shapes.add(rectangle); ClsView view = new ClsView(); //將List放入畫面View view.setShapes(shapes); ObjectMapper mapper = new ObjectMapper(); System.out.println("-- 序列化 --"); String jsonStr = mapper.writeValueAsString(view); System.out.println(jsonStr); System.out.println("-- 反序列化 --"); ClsView deserializeView = mapper.readValue(jsonStr, ClsView.class); System.out.println(deserializeView);}大家看最終在控制臺的輸出結果如下:序列化的過程是正常的,但是反序列化的時候報錯了。

-- 序列化 --{"shapes":[{"radius":8},{"width":7,"height":9}]}-- 反序列化 --com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "radius" (class com.example.demo.javabase.ClsShape), not marked as ignorable (0 known properties: ]) at [Source: (String)"{"shapes":[{"radius":8},{"width":7,"height":9}]}"; line: 1, column: 23] (through reference chain: com.example.demo.javabase.ClsView["shapes"]->java.util.ArrayList[0]->com.example.demo.javabase.ClsShape["radius"])拋出異常的主要原因是我們用來接收反序列化的結果時,使用的是List<ClsShape>,Java程序並不明確的知道,這個ClsShape形狀是圓形ClsCircle,還是正方形ClsRectangle。所以無法將字符串正確的反序列化為java對象。

三、@JsonTypeInfo註解加到父類定義上

為了解決上面的這種繼承關係對象的反序列化出現的問題,jackson為我們提供了JsonTypeInfo註解,把它加在父類定義上面即可。

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)public class ClsShape {}在父類定義上面加上@JsonTypeInfo註解之後,序列化與反序列化的輸出結果如下。

-- 序列化 --{"shapes":[{"@class":"com.example.demo.javabase.ClsCircle","radius":8},{"@class":"com.example.demo.javabase.ClsRectangle","width":7,"height":9}]}-- 反序列化 --ClsView(shapes=[ClsCircle(radius=8), ClsRectangle(width=7, height=9)])值得注意的是在序列化之後的java字符串中,每個Json對象都包含了一個新的屬性@class,這也是該對象在繼承關係下能夠反序列化為正確的java對象(@class的值的類對象)的關鍵所在。

四、@JsonTypeInfo註解加到包含父類的成員變量上面

@JsonTypeInfo註解不僅可以加在父類的定義上面,也可以加到包含父類的成員變量上面。序列化和反序列化的結果和第三小節中的內容是一樣的。

@Datapublic class ClsView { @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) private List<ClsShape> shapes;}歡迎關注我的博客,裡面有很多精品合集

本文轉載註明出處(必須帶連接,不能只轉文字):字母哥博客。覺得對您有幫助的話,幫我點讚、分享!您的支持是我不竭的創作動力! 。另外,筆者最近一段時間輸出了如下的精品內容,期待您的關注。

《手摸手教你學Spring Boot2.0》《Spring Security-JWT-OAuth2一本通》《實戰前後端分離RBAC權限管理系統》《實戰SpringCloud微服務從青銅到王者》《VUE深入淺出系列》

相關焦點

  • 工具類JsonUtils完成json的序列化和反序列化
    而Java中數據的體現方法無外乎就是對象,所以會涉及到Json字符串的序列化與反序列化。一、Json的序列化JsonUtils工具類非常地強大,一共有5個方法,可以完成json字符串的各種轉化。第1個if條件語句判斷對象是否為空。第2個if條件語句判斷對象類型是否是字符串,mapper調用writeValueAsString()方法可以將對象轉換成json字符串。Java普通對象,list集合以及map集合都可以直接使用該方法直接實現轉換。
  • 如何實現一個優雅的Python的Json序列化庫
    Python標準庫裡面提供了json序列化的工具,我們可以簡單的用json.dumps來將一個對象序列化。但是這種序列化僅支持python內置的基本類型,對於自定義的類,我們將得到Object of type A is not JSON serializable的錯誤。
  • JSON數據處理框架Jackson-序列化與反序列化核心用法
    它雖然簡單易用,但絕對不是小玩具,本節為大家介紹Jackson的基礎核心用法,更多的內容我會寫成一個系列,5-10篇文章,請您繼續關注我。一、基礎準備在任意項目中引入下面的jar就可以使用jackson進行JSON的數據序列化與反序列化的功能。
  • Jaskson精講第6篇-自定義JsonSerialize與Deserialize實現數據類型...
    《序列化與反序列化核心用法-JSON框架Jackson精解第1篇》《特殊數據格式處理-JSON框架Jackson精解第2篇》《屬性序列化自定義排序與字母表排序-JSON框架Jackson精解第3篇》《@JacksonInject與@JsonAlias註解-JSON框架Jackson精解第4篇》《@JsonCreator自定義反序列化函數-JSON框架Jackson精解第5篇》本節繼續為大家介紹在
  • JSON利器之Jackson 序列化與反序列化常用註解解密
    概述Jackson 屬於轉換json的重要工具,同時由於Spring boot 默認使用Jackson,了解下Jackson 序列化很有必要。序列化@JsonAnyGetter@JsonAnyGetter 把Map中的 每個key都轉成一個屬性。1.將非靜態和無參數方法定義為「any getter"。
  • Protobuf 入門級指南(谷歌的序列化框架,類似json,但更快)
    最近公司有用到Protobuf這個序列化框架,以前從來沒用過,所以今天學習了下,入個門。Protobuf 是一種與平臺和語言無關的序列化框架,常用於通信協議,數據存儲等。優點:它的速度比xml和json更快,同時他能將數據壓縮的更小,對於結構化數據優勢更明顯。什麼是結構化數據呢?就是帶有一定結構的數據。
  • JAVA對象的序列化與反序列化
    概述WHAT對象的序列化對象的反序列化PROTOBUFFERWHYHOW使用JDK類庫把對象包裝成JSON字符串總結1. WHAT將對象轉化為字節序列的過程稱為對象的序列化將字節序列恢復為對象的過程稱為對象的反序列化2.
  • Jackson進行JSON解析和序列化
    Java下常見的Json類庫有Gson、JSON-lib和Jackson等,Jackson相對來說比較高效,在項目中主要使用Jackson進行JSON和Java對象轉換,下面給出一些Jackson的JSON操作方法。
  • ASP.NET中JSON的序列化和反序列化
    在網站應用中使用JSON的場景越來越多,本文介紹 ASP.NET中JSON的序列化和反序列化,主要對JSON的簡單介紹,ASP.NET如何序列化和反序列化的處理,在序列化和反序列化對日期時間、集合、字典的處理。一、JSON簡介JSON(JavaScript Object Notation,JavaScript對象表示法)是一種輕量級的數據交換格式。
  • json從立地到成佛
    而非關係型的資料庫由於它本身的特點得到非常迅速的發展,非關係資料庫在大規模數據下也有非常良好的讀寫性能,且數據之間無關係,無形之間就在架構層面帶來了可拓展的能力。而有很多基於文檔存儲的非關係資料庫採取json作為其存儲格式,其中比較著名的有:MongoDB、CouchDB、RavenDB等。存儲的內容是文檔型的,這樣也有機會對某些欄位建立索引,實現關係資料庫的某些功能。
  • Jackson,最牛掰的 Java JSON 解析器
    當 Jackson 默認序列化和反序列化不能滿足實際的開發需要時,可以自定義新的序列化和反序列化類。自定義的序列化類需要繼承 StdSerializer,同時重寫 serialize() 方法,利用 JsonGenerator 生成 JSON,示例如下:public class CustomSerializer
  • 從零開始學Python:24課-對象的序列化和反序列化
    在趁著有時間,趕緊再更新篇Python教程!還是接著上期的講哈。讀寫JSON格式的數據通過上面的講解,我們已經知道如何將文本數據和二進位數據保存到文件中,那麼這裡還有一個問題,如果希望把一個列表或者一個字典中的數據保存到文件中又該怎麼做呢?
  • golang json 性能分析
    Go 語言裡面原生支持了這種數據格式的序列化以及反序列化,內部使用反射機制實現,性能有點差,在高度依賴 json 解析的應用裡,往往會成為性能瓶頸,好在已有很多第三方庫幫我們解決了這個問題,但是這麼多庫,對於像我這種有選擇困難症的人來說,到底要怎麼選擇呢,下面就給大家來一一分析一下原生的庫性能比較差的主要原因是使用了很多反射的機制,為了解決這個問題,ffjson 通過預編譯生成代碼,類型的判斷在預編譯階段已經確定
  • Python3內置模塊之json編解碼方法小結
    下面為Python對象-->JSON對象的對照關係表。dumps編碼我們利用dumps將Python對象編碼為JSON對象,當然dumps只完成了序列化為str,而dump必須傳文件描述符,將序列化的str保存到文件中,它們的函數定義為dumps(obj, *, skipkeys=False, ensure_ascii
  • struct2json V1.0 發布,C 結構體與 JSON 互轉庫
    struct2json 是一個開源的C結構體與 JSON 快速互轉庫,它可以快速實現 結構體對象 與 JSON 對象 之間序列化及反序列化要求
  • 使用JSON JavaScriptSerializer 進行序列化或反序列化時出錯
    在ASP.NET 開發中,我們在後臺邏輯方法中將500條以上DataTable中的數據進行JSON序列化時,我們通過在Visual Studio中調試發現,已經序列化後的JSON數據類似如下圖所示:首先我們要檢查下序列化後的JSON數據格式是否正確,我們拷貝調試過程中生成的JSON
  • Python3內置模塊之json編碼解碼方法講解
    Python3中我們利用內置模塊json解碼和編碼JSON對象。將Python對象編碼為 JSON對象 ,當然 dumps 只完成了序列化為str,而 dump 必須傳文件描述符,將序列化的str保存到文件中。
  • JSONQuery v0.2.5,更簡單的使用 Gson 解析 JSON
    Post post = JSONQuery.select(json, "comment_info > [2]", Post.class);//將選擇結果反序列化為普通對象數組Post[] postArray = JSONQuery.select(json, "comment_info", Post[].class);//將選擇結果反序列化為泛型類型List<Post>Type type
  • Swoole 4.5.6 支持零拷貝 JSON 或 PHP 反序列化
    使用Swoole\Server實現RPC服務,在EOF協議或長度協議通信方式下,一個包可能有3部分組成。$packet = $header + $body + $footer通常$header和$footer比較小,而$body比較大,$body可能會使用JSON或PHP序列化格式。
  • 乾貨|如何利用Python處理JSON格式的數據,建議收藏!
    和pickle兩個json模塊和pickle都提供了四個方法:dumps, dump, loads, load序列化:將python的數據轉換為json格式的字符串反序列化:將json格式的字符串轉換成python的數據類型