1. 程式人生 > >URL及日期等特殊資料格式處理-JSON框架Jackson精解第2篇

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

![](https://img2020.cnblogs.com/other/1815316/202009/1815316-20200920095431256-1928206551.png) Jackson是Spring Boot預設的JSON資料處理框架,但是其並不依賴於任何的Spring 庫。有的小夥伴以為Jackson只能在Spring框架內使用,其實不是的,沒有這種限制。它提供了很多的JSON資料處理方法、註解,也包括**流式API、樹模型、資料繫結**,以及複雜資料型別轉換等功能。它雖然簡單易用,但絕對不是小玩具,本節為大家介紹Jackson的基礎核心用法,**更多的內容我會寫成一個系列,5-10篇文章,請您繼續關注我。** * 在 [《序列化與反序列化核心用法-JSON框架Jackson精解第一篇》](http://www.zimug.com/java/spring/%e5%ba%8f%e5%88%97%e5%8c%96%e4%b8%8e%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e6%a0%b8%e5%bf%83%e7%94%a8%e6%b3%95-json%e6%a1%86%e6%9e%b6jackson%e7%b2%be%e8%a7%a3%e7%ac%ac%e4%b8%80%e7%af%87/.html) 也就是上一篇中,為大家介紹了這些內容 * 一、基礎準備 * 二、序列化方法 * 三、反序列化方法 * 四、欄位重新命名`@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 類的成員變數。 ![](https://img2020.cnblogs.com/other/1815316/202009/1815316-20200920095431627-1788728165.png) 比如上圖中的兩個類, * 我們先將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"} ~~~ ## 歡迎關注我的部落格,裡面有很多精品合集 * 本文轉載註明出處(必須帶連線,不能只轉文字):[字母哥部落格](http://www.zimug.com)。 **覺得對您有幫助的話,幫我點贊、分享!您的支援是我不竭的創作動力!** 。另外,筆者最近一段時間輸出瞭如下的精品內容,期待您的關注。 * [《手摸手教你學Spring Boot2.0》]( https://www.kancloud.cn/hanxt/springboot2/content ) * [《Spring Security-JWT-OAuth2一本通》](https://www.kancloud.cn/hanxt/springsecurity/content) * [《實戰前後端分離RBAC許可權管理系統》](https://www.kancloud.cn/hanxt/vue-spring/content) * [《實戰SpringCloud微服務從青銅到王者》](https://www.kancloud.cn/hanxt/springcloud/content) * [《VUE深入淺出系列》](https://www.kancloud.cn/hanxt/vuejs2/