Jackson是Spring Boot預設的JSON資料處理框架,但是其並不依賴於任何的Spring 庫。有的小夥伴以為Jackson只能在Spring框架內使用,其實不是的,沒有這種限制。它提供了很多的JSON資料處理方法、註解,也包括流式API、樹模型、資料繫結,以及複雜資料型別轉換等功能。它雖然簡單易用,但絕對不是小玩具,本節為大家介紹Jackson的基礎核心用法,更多的內容我會寫成一個系列,5-10篇文章,請您繼續關注我。
- 在 《序列化與反序列化核心用法-JSON框架Jackson精解第一篇》 也就是上一篇中,為大家介紹了這些內容
- 一、基礎準備
- 二、序列化方法
- 三、反序列化方法
- 四、欄位重新命名
@JsonProperty
- 五、忽略null欄位的序列化
@JsonInclude
- 六、忽略指定的欄位
本篇文章中為大家介紹,一些特殊JOSN資料格式處理-JSON框架Jackson精解第2篇:
- 一、從URL讀取JSON資料
- 二、Unknow Properties 賦值失敗處理
- 三、未賦值Java Bean序列化
- 四、日期格式化
一、從URL讀取JSON資料
Jackson不僅可以將字串反序列化為 Java POJO物件,還可以請求遠端的API,獲得遠端服務的JSON響應結果,並將其轉換為Java POJO物件。
@Test
void testURL() throws IOException {
URL url = new URL("https://jsonplaceholder.typicode.com/posts/1"); //遠端服務URL
ObjectMapper mapper = new ObjectMapper();
//從URL獲取JSON響應資料,並反序列化為java 物件
PostDTO postDTO = mapper.readValue(url, PostDTO.class);
System.out.println(postDTO);
}
jsonplaceholder.typicode.com
是一個免費提供HTTP測試服務的網站,我們可以利用它進行測試- 遠端服務API返回結果是一個JSON字串,一篇post稿件包含userId,id,title,content屬性
- PostDTO 是我們自己定義的java 類,同樣包含userId,id,title,content成員變數
下文是控制檯列印輸出結果,postDTO的toString()方法輸出。
PostDTO(userId=1, id=1, title=sunt aut facere repellat provident occaecati excepturi optio reprehenderit, body=quia et suscipit
suscipit recusandae consequuntur expedita et cum
reprehenderit molestiae ut ut quas totam
nostrum rerum est autem sunt rem eveniet architecto)
二、Unknow Properties 賦值失敗處理
有的時候,客戶端提供的JSON字串屬性,多於我們服務端定義的java 類的成員變數。
比如上圖中的兩個類,
- 我們先將PlayerStar序列化為JSON字串,包含age屬性
- 然後將JSON字串轉換為PlayerStar2,不包含age屬性
@Test
void testUnknowProperties() throws IOException {
ObjectMapper mapper = new ObjectMapper();
PlayerStar player = PlayerStar.getInstance(); //為PlayerStar 各屬性賦值,可以參考本系列文章第一篇
//將PlayerStar序列化為JSON字串
String jsonString = mapper.writeValueAsString(player);
System.out.println(jsonString);
//將JSON字串反序列化為PlayerStar2物件
PlayerStar2 player2 = mapper.readValue(jsonString, PlayerStar2.class);
System.out.println(player2);
}
當進行反序列化的時候,會丟擲下面的異常。這是因為JSON字串所包含的屬性,多餘Java類的定義(多出一個阿age,賦值時找不到setAge方法)。
{"age":45,"playerName":"喬丹"}
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "age" (class com.example.demo.javabase.PlayerStar2), not marked as ignorable (one known property: "playerName"])
at [Source: (String)"{"age":45,"playerName":"喬丹"}"; line: 1, column: 10] (through reference chain: com.example.demo.javabase.PlayerStar2["age"])
如果我們想忽略掉age屬性,不接受我們的java類未定義的成員變數資料,可以使用下面的方法,就不會丟擲UnrecognizedPropertyException了。
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
三、未賦值Java Bean序列化
有的時候,我們明知道某些類的資料可能為空,我們通常也不會為它賦值。但是客戶端就是需要這個{}
的JSON物件,我們該怎麼做?
public class MyEmptyObject {
private Integer i; //沒有get set方法
}
我們可以為ObjectMapper設定disable序列化特性:FAIL_ON_EMPTY_BEANS,也就是允許物件的所有屬性均未賦值。
@Test
void testEmpty() throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
String jsonString = mapper.writeValueAsString(new MyEmptyObject());
System.out.println(jsonString);
}
預設情況下不做設定,會丟擲下面的異常InvalidDefinitionException。設定disable序列化特性:FAIL_ON_EMPTY_BEANS之後,會序列化為{}
字串。
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.example.demo.jackson.JacksonTest1$MyEmptyObject and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
四、日期格式化
日期格式化,是我們JSON序列化與反序列化過程中比較常見的需求
ObjectMapper mapper = new ObjectMapper();
Map temp = new HashMap();
temp.put("now", new Date());
String s = mapper.writeValueAsString(temp);
System.out.println(s);
預設情況下,針對java中的日期及相關型別,Jackson的序列化結果如下
{"now":1600564582571}
如果我們希望在JSON序列化及反序列化過程中,日期格式化,需要做如下的處理
ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); //注意這裡
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); //注意這裡
Map temp = new HashMap();
temp.put("now", new Date());
String s = mapper.writeValueAsString(temp);
System.out.println(s);
控制檯列印輸出結果如下:
{"now":"2020-09-20"}
歡迎關注我的部落格,裡面有很多精品合集
- 本文轉載註明出處(必須帶連線,不能只轉文字):字母哥部落格。
覺得對您有幫助的話,幫我點贊、分享!您的支援是我不竭的創作動力! 。另外,筆者最近一段時間輸出瞭如下的精品內容,期待您的關注。