Jackson是Spring Boot(SpringBoot)默認的JSON數據處理框架,可是其並不依賴於任何的Spring 庫。有的小夥伴覺得Jackson只能在Spring框架內使用,其實不是的,沒有這種限制。它提供了不少的JSON數據處理方法、註解,也包括流式API、樹模型、數據綁定,以及複雜數據類型轉換等功能。它雖然簡單易用,但絕對不是小玩具,更多的內容我會寫成一個系列,5-10篇文章,請您繼續關注我。html
本篇文章是系列文章的第7篇,主要是爲你們介紹一下,在Java 類繼承的狀況下如何實現父類及子類的JSON序列化與反序列化。vue
首先構建一個ClsShape類表示形狀。java
public class ClsShape { }
構建一個ClsCircle 類表示圓形。並添加了一系列的lombok註解,Data表示提供get、set、toString、hashCode等方法;EqualsAndHashCode註解在有繼承關係的字類中使用;AllArgsConstructor和NoArgsConstructor分別提供全參和無參構造方法。spring
@Data @EqualsAndHashCode(callSuper = true) @AllArgsConstructor @NoArgsConstructor public class ClsCircle extends ClsShape { Integer radius; //弧度 }
構建一個長方形類ClsRectangle ,成員變量width寬度,height高度。json
@Data @EqualsAndHashCode(callSuper = true) @AllArgsConstructor @NoArgsConstructor public class ClsRectangle extends ClsShape { private Integer width; private Integer height; }
構建一個ClsView類,表示畫面。畫面中有不少的ClsShape形狀,因此用一個List封裝。後端
@Data public class ClsView { private List<ClsShape> shapes; }
基礎的形狀類及畫面類寫完以後,下面的代碼是用來完成:對象到Json字符串的序列化過程,和Json字符串反序列化爲Java對象的過程代碼。springboot
@Test void 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); }
你們看最終在控制檯的輸出結果以下:序列化的過程是正常的,可是反序列化的時候報錯了。app
-- 序列化 -- {"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
註解不只能夠加在父類的定義上面,也能夠加到包含父類的成員變量上面。序列化和反序列化的結果和第三小節中的內容是同樣的。
@Data public class ClsView { @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) private List<ClsShape> shapes; }
本文轉載註明出處(必須帶鏈接,不能只轉文字):字母哥博客 - zimug.com
以爲對您有幫助的話,幫我點贊、分享!您的支持是我不竭的創做動力! 。另外,筆者最近一段時間輸出了以下的精品內容,期待您的關注。