URL及日期等特殊資料格式處理-JSON框架Jackson精解第2篇

字母哥部落格發表於2020-09-20

Jackson是Spring Boot預設的JSON資料處理框架,但是其並不依賴於任何的Spring 庫。有的小夥伴以為Jackson只能在Spring框架內使用,其實不是的,沒有這種限制。它提供了很多的JSON資料處理方法、註解,也包括流式API、樹模型、資料繫結,以及複雜資料型別轉換等功能。它雖然簡單易用,但絕對不是小玩具,本節為大家介紹Jackson的基礎核心用法,更多的內容我會寫成一個系列,5-10篇文章,請您繼續關注我。

本篇文章中為大家介紹,一些特殊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"}

歡迎關注我的部落格,裡面有很多精品合集

  • 本文轉載註明出處(必須帶連線,不能只轉文字):字母哥部落格

覺得對您有幫助的話,幫我點贊、分享!您的支援是我不竭的創作動力! 。另外,筆者最近一段時間輸出瞭如下的精品內容,期待您的關注。

相關文章