Jackson 概述 與 依賴
1、市面上用於在 Java 中解析 Json 的第三方庫,隨便一搜不下幾十種,其中的佼佼者有 Google 的 Gson, Alibaba 的 Fastjson 以及本文的 jackson。
2、三者不相伯仲,隨着掌握一個都能滿足項目中的 json 解析操作,因為 Spring Boot Web 組件默認使用的是 jackson,所以掌握 Jackjson 是非常有必要的。
3、gson 和 fastjson 使用時只需要導入一個 jar 包(或者一個依賴)即可,而 jackson 卻不是全部集成在一個 jar (一個應用)內,而是分為不同的功能模塊,需要使用哪些功能,則導入對應的 jar 包(或依賴)。
FasterXml Github 地址:https://github.com/FasterXML,jackson 所有的功能模塊都在其中 比如 jackson-core 模塊:https://github.com/FasterXML/jackson-core,其中提供了 maven 依賴: |
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <!-- 如可以使用最新的 2.9.7、2.9.8 版本 --> <version>${jackson.version.core}</version> </dependency>
jackson-core 二進制 jar 包下載地址:http://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/ 其余的 jackson-xxx 模塊也是同理,在其相應的項目主頁中,都提供 maven 依賴與下載 jar 地址。 |
4、看了上面 Spring Boot Web 組件依賴 jackson 的情況就知道,使用 Jackson 導入以下 3 個主要模塊基本滿足開發:
5、其中 jackson-databind 內部依賴了 jackson-annotations 與 jackson-core,所以 Maven 應用時,只要導入 databind 一個,則同時也導入了 annotations 與 core 依賴。
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.0</version> </dependency>
Jackson 使用前情提要
1、默認情況下,ObjectMapper 在序列化對象時,將實體所有的字段一 一序列化,無論這些字段是否有值,是否為 null。
2、如果實體的某個字段沒有提供 getter 方法,則該字段不會被序列化。
3、Spring Boot Web 組件默認使用 jackson 進行對象的序列化與反序列化,即頁面傳入的參數,會自動反序列化為后台對象,后台傳給前端的對象,也會序列化后輸出。所以需要注意返回給頁面的對象默認不能使用 Jackson 以外的 Json 庫序列化,比如返回一個 Gson 的 JsonObject 給前端,則會報錯,因為顯然 Jackson 序列化時會失敗。
4、Jackson 提供三種不同的方法來操作 JSON:
1)流式API - 使用 Stream(流) 的方式對 Json 的每一個組成部分進行最細粒度的控制,JsonParser 讀取數據,JsonGenerator 寫入數據。 2)樹模型 - 將 JSON 文件在內存里以樹的形式表示,通過 JsonNode 處理單個Json節點,類似於 XML 的 DOM 解析器。(常用) 3)databind 模塊 - ObjectMapper 讀/寫 JSON 是 POJO 序列化與反序列化 json 最方便的方式。(常用) |
ObjectMapper 序列化對象
1、ObjectMapper 主要用於對 Java 對象(比如 POJO、List、Set、Map 等等)進行序列化與反序列化。
2、ObjectMapper 除了能在 json 字符串與 Java 對象之間進行轉換,還能將 json 字符串與 JsonNode 進行轉換。
Java 對象與 Json 字符串的轉換 | |
String writeValueAsString(Object value) | 1、用於將任何 Java 對象(如 POJO、List、Set、Map等)序列化為 json 字符串,如果對象中某個屬性的值為 null,則默認也會序列化為 null; 2、如果 value 為 null,返回序列化的結果也返回 null |
byte[] writeValueAsBytes(Object value) |
將 java 對象序列化為 字節數組 |
writeValue(File resultFile, Object value) |
將 java 對象序列化並輸出指定文件中 |
writeValue(OutputStream out, Object value) |
將 java 對象序列化並輸出到指定字節輸出流中 |
writeValue(Writer w, Object value) |
將 java 對象序列化並輸出到指定字符輸出流中 |
T readValue(String content, Class<T> valueType) | 1、從給定的 JSON 字符串反序列化為 Java 對象; 2、content 為空或者為 null,都會報錯 |
T readValue(byte[] src, Class<T> valueType) | 將 json 內容的字節數組反序列化為 java 對象 |
T readValue(File src, Class<T> valueType) | 將本地 json 內容的文件反序列化為 java 對象 |
T readValue(InputStream src, Class<T> valueType) | 將 json 內容的字節輸入流反序列化為 java 對象 |
T readValue(Reader src, Class<T> valueType) | 將 json 內容的字符輸入流反序列化為 java 對象 |
T readValue(URL src, Class<T> valueType) |
通過網絡 url 地址將 json 內容反序列化為 java 對象 |
Json 字符串內容反序列化為 Json 節點對象 | |
JsonNode readTree(String content) | 將 JSON 字符串反序列化為 JsonNode 對象,即 json 節點對象 |
JsonNode readTree(URL source) | 對網絡上的 json 文件進行反序列化為 json 節點對象 |
JsonNode readTree(InputStream in) | 對 json 文件輸入流進行反序列化為 json 節點對象 |
JsonNode readTree(byte[] content) | 對 json 字節數組反序列化為 json 節點對象 |
JsonNode readTree(File file) | 將本地 json 文件反序列為為 json 節點對象 |
Java 對象與 Json 節點對象的轉換 | |
T convertValue(Object fromValue, Class<T> toValueType) | 將 Java 對象(如 POJO、List、Map、Set 等)序列化為 Json 節點對象。 |
T treeToValue(TreeNode n, Class<T> valueType) | json 樹節點對象轉 Java 對象(如 POJO、List、Set、Map 等等) TreeNode 樹節點是整個 json 節點對象模型的根接口。 |
API 演示源碼:/src/main/java/com/wmx/jackson/ObjectMapperTest.java

package com.wmx.jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Test; import javax.swing.filechooser.FileSystemView; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.net.URL; import java.util.*; /** * {@link ObjectMapper} 用於對 Java 對象(比如 POJO、List、Set、Map 等等)進行序列化與反序列化 * * @author wangMaoXiong * @version 1.0 * @date 2020/7/16 14:34 */ @SuppressWarnings("all") public class ObjectMapperTest { /** * POJO 對象轉 json 字符串 * String writeValueAsString(Object value) * 1、該方法可用於將任何 Java 值、對象序列化為 json 字符串,如果對象中某個屬性的值為 null,則默認也會序列化為 null * 2、value 為 null,返回 null * * @throws JsonProcessingException */ @Test public void writeValueAsString1() throws JsonProcessingException { User user = new User(1000, "張三", new Date(), null); ObjectMapper objectMapper = new ObjectMapper(); String json = objectMapper.writeValueAsString(user); System.out.println(json); //{"uId":1000,"uName":"張三","birthday":1594881355832,"price":null} } /** * String writeValueAsString(Object value) * 1、 Java 值、對象序列化為 json 字符串,value 可以是任意的 java 對象,比如 POJO、list、Map、Set 等等 */ @Test public void writeValueAsString2() { try { List<User> userList = new ArrayList<>(2); User user1 = new User(1000, "張三", null, 7777.88F); User user2 = new User(2000, "李四", new Date(), 9800.78F); userList.add(user1); userList.add(user2); ObjectMapper objectMapper = new ObjectMapper(); String json = objectMapper.writeValueAsString(userList); //[{"uId":1000,"uName":"張三","birthday":null,"price":7777.88},{"uId":2000,"uName":"李四","birthday":1594882217908,"price":9800.78}] System.out.println(json); } catch (IOException e) { e.printStackTrace(); } } /** * String writeValueAsString(Object value) * 1、 Java 值、對象序列化為 json 字符串,value 可以是任意的 java 對象,比如 POJO、list、Map、Set 等等 */ @Test public void writeValueAsString3() throws JsonProcessingException { try { Map<String, Object> dataMap = new HashMap<>(); dataMap.put("uId", 9527); dataMap.put("uName", "華安"); dataMap.put("birthday", new Date()); dataMap.put("price", 9998.45F); dataMap.put("marry", null); ObjectMapper objectMapper = new ObjectMapper(); //{"birthday":1594884443501,"uId":9527,"uName":"華安","price":9998.45,"marry":null} String json = objectMapper.writeValueAsString(dataMap); System.out.println(json); } catch (IOException e) { e.printStackTrace(); } } /** * writeValue(File resultFile, Object value) * 1、 Java java 對象,比如 POJO、list、Map、Set 等等 序列化並輸出到指定文件中 * 2、文件不存在時,會自動新建 */ @Test public void writeValueAsString4() throws JsonProcessingException { try { Map<String, Object> dataMap = new HashMap<>(); dataMap.put("uId", 9527); dataMap.put("uName", "華安2"); dataMap.put("birthday", new Date()); dataMap.put("price", 9998.45F); dataMap.put("marry", null); File homeDirectory = FileSystemView.getFileSystemView().getHomeDirectory(); File jsonFile = new File(homeDirectory, "wmx2.json"); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.writeValue(jsonFile, dataMap); System.out.println("輸出 json 文件:" + jsonFile.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } } /** * T readValue(String content, Class<T> valueType) * 1、從給定的 JSON 內容字符串反序列化為對象 * 2、content 為空或者為 null,都會報錯 * 3、valueType 表示反序列號的結果對象,可以是任何 java 對象,比如 POJO、List、Set、Map 等等. */ @Test public void readValue1() { try { String json = "{\"uId\":1000,\"uName\":\"張三\",\"birthday\":1594881355832,\"price\":null}"; ObjectMapper objectMapper = new ObjectMapper(); User user = objectMapper.readValue(json, User.class); //User{uId=1000, uName='張三', birthday=Thu Jul 16 14:35:55 CST 2020, price=null} System.out.println(user); } catch (IOException e) { e.printStackTrace(); } } /** * T readValue(String content, Class<T> valueType) * 1、從給定的 JSON 內容字符串反序列化為對象 * 2、content 為空或者為 null,都會報錯 * 3、valueType 表示反序列號的結果對象,可以是任何 java 對象,比如 POJO、List、Set、Map 等等. */ @Test public void readValue2() { try { String json = "[{\"uId\":1000,\"uName\":\"張三\",\"birthday\":null,\"price\":7777.88},{\"uId\":2000,\"uName\":\"李四\",\"birthday\":1594882217908,\"price\":9800.78}]"; ObjectMapper objectMapper = new ObjectMapper(); List<User> userList = objectMapper.readValue(json, List.class); //{uId=2000, uName=李四, birthday=1594882217908, price=9800.78} System.out.println(userList.get(1)); } catch (IOException e) { e.printStackTrace(); } } /** * T readValue(String content, Class<T> valueType) * 1、從給定的 JSON 內容字符串反序列化為對象 * 2、content 為空或者為 null,都會報錯 * 3、valueType 表示反序列號的結果對象,可以是任何 java 對象,比如 POJO、List、Set、Map 等等. */ @Test public void readValue3() { try { String json = "{\"birthday\":1594884443501,\"uId\":9527,\"uName\":\"華安\",\"price\":9998.45,\"marry\":null}"; ObjectMapper objectMapper = new ObjectMapper(); Map map = objectMapper.readValue(json, Map.class); //{birthday=1594884443501, uId=9527, uName=華安, price=9998.45, marry=null} System.out.println(map); } catch (IOException e) { e.printStackTrace(); } } /** * T readValue(File src, Class<T> valueType):將本地 json 內容文件反序列為 Java 對象 */ @Test public void readTree4() { try { String json = "[{\"uId\":1000,\"uName\":\"張三\",\"birthday\":null,\"price\":7777.88},{\"uId\":2000,\"uName\":\"李四\",\"birthday\":1594882217908,\"price\":9800.78}]"; File homeDirectory = FileSystemView.getFileSystemView().getHomeDirectory(); File jsonFile = new File(homeDirectory, "wmx.json"); if (!jsonFile.exists()) { FileWriter fileWriter = new FileWriter(jsonFile); fileWriter.write(json); fileWriter.flush(); fileWriter.close(); System.out.println("輸出 json 文件:" + jsonFile.getAbsolutePath()); } List<User> userList = new ObjectMapper().readValue(jsonFile, List.class); //{uId=2000, uName=李四, birthday=1594882217908, price=9800.78} System.out.println(userList.get(1)); } catch (Exception e) { e.printStackTrace(); } } /** * JsonNode readTree(String content):將 JSON 內容反序列化為 JsonNode 對象 * * @throws IOException */ @Test public void readTree1() throws IOException { //被解析的 json 格式的字符串 String json = "{\"notices\":[{\"title\":\"停水\",\"day\":\"1\"},{\"title\":\"停電\",\"day\":\"3\"},{\"title\":\"停網\",\"day\":\"2\"}]}"; ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readTree(json); System.out.println(jsonNode); } /** * JsonNode readTree(URL source) :對網絡上的 json 文件進行反序列化為 json 節點對象 */ @Test public void readTree2() { try { URL url = new URL("http://t.weather.sojson.com/api/weather/city/101030100"); JsonNode jsonNode = new ObjectMapper().readTree(url); System.out.println(jsonNode); } catch (Exception e) { e.printStackTrace(); } } /** * JsonNode readTree(File file):將本地 json 文件反序列化為 json 節點對象 */ @Test public void readTree3() { try { String json = "[{\"uId\":1000,\"uName\":\"張三\",\"birthday\":null,\"price\":7777.88},{\"uId\":2000,\"uName\":\"李四\",\"birthday\":1594882217908,\"price\":9800.78}]"; File homeDirectory = FileSystemView.getFileSystemView().getHomeDirectory(); File jsonFile = new File(homeDirectory, "wmx.json"); if (!jsonFile.exists()) { FileWriter fileWriter = new FileWriter(jsonFile); fileWriter.write(json); fileWriter.flush(); fileWriter.close(); System.out.println("輸出 json 文件:" + jsonFile.getAbsolutePath()); } JsonNode jsonNode = new ObjectMapper().readTree(jsonFile); System.out.println(jsonNode.get(0));//{"uId":1000,"uName":"張三","birthday":null,"price":7777.88} } catch (Exception e) { e.printStackTrace(); } } /** * T treeToValue(TreeNode n, Class<T> valueType):json 節點對象轉 Java 對象(如 POJO、List、Set、Map 等等) */ @Test public void test() { try { ObjectNode objectNode = JsonNodeFactory.instance.objectNode(); objectNode.put("uId", 3200); objectNode.put("uName", "李世民"); objectNode.put("birthday", new Date().getTime()); User user = new ObjectMapper().treeToValue(objectNode, User.class); //User{uId=3200, uName='李世民', birthday=Fri Jul 17 20:34:13 CST 2020, price=null} System.out.println(user); } catch (JsonProcessingException e) { e.printStackTrace(); } } /** * T convertValue(Object fromValue, Class<T> toValueType) * 1、將 Java 對象(如 POJO、List、Map、Set 等)序列化為 Json 節點對象,通常有以下兩種方式: * 2、一種方式是先序列化為 json 字符串,然后 readTree 反序列化為 Json 節點 * 3、還有就是使用此種方式進行轉換,將 java 對象直接轉換為 json 節點。 */ @Test public void convertValue1() { User user = new User(1000, "張三", new Date(), null); ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.convertValue(user, JsonNode.class); //{"uId":1000,"uName":"張三","birthday":1594967015825,"price":null} System.out.println(jsonNode); } @Test public void convertValue2() { Map<String, Object> dataMap = new HashMap<>(); dataMap.put("uId", 9527); dataMap.put("uName", "華安"); dataMap.put("birthday", new Date()); dataMap.put("price", 9998.45F); dataMap.put("marry", null); ObjectMapper objectMapper = new ObjectMapper(); JsonNode objectNode = objectMapper.convertValue(dataMap, JsonNode.class); //{"birthday":1594950930586,"uId":9527,"uName":"華安","price":9998.45,"marry":null} System.out.println(objectNode); } @Test public void convertValue3() { List<User> userList = new ArrayList<>(2); User user1 = new User(1000, "張三", null, 7777.88F); User user2 = new User(2000, "李四", new Date(), 9800.78F); userList.add(user1); userList.add(user2); ObjectMapper objectMapper = new ObjectMapper(); JsonNode objectNode = objectMapper.convertValue(userList, JsonNode.class); //[{"uId":1000,"uName":"張三","birthday":null,"price":7777.88},{"uId":2000,"uName":"李四","birthday":1594967168878,"price":9800.78}] System.out.println(objectNode); } }
JsonNode 樹模型 Json 節點
1、JsonNode 表示 json 節點,整個節點模型的根接口為 TreeNode,json 節點主要用於手動構建 json 對象。
2、JsonNode 有各種數據類型的實現類,其中最常用的就是 ObjectNode 與 ArrayNode,前者表示 json 對象,后者表示 json 對象數組。
3、json 節點對象可以通過 JsonNodeFactory 創建,如 JsonNodeFactory.instance.objectNode();
JsonNode json節點通用方法 | |
JsonNode get(String fieldName) | 用於訪問對象節點的指定字段的值,如果此節點不是對象、或沒有指定字段名的值,或沒有這樣名稱的字段,則返回 null。 |
JsonNode get(int index)JsonNode get(int index) | 訪問數組節點的指定索引位置上的值,對於其他節點,總是返回 null. 如果索引小於0,或等於、大於節點大小,則返回 null,對於任何索引都不會引發異常。 |
boolean isArray() | 判斷此節點是否為 {@link ArrayNode} 數組節點 |
boolean isObject() | 如果此節點是對象節點,則返回 true,否則返回 false |
int size() | 獲取 json 節點的大小,比如 json 對象中有多少鍵值對,或者 json 數組中有多少元素。 |
ObjectNode deepCopy() | json 節點對象深度復制,相當於克隆 |
Iterator<String> fieldNames() | 獲取 json 對象中的所有 key |
Iterator<JsonNode> elements() | 如果該節點是JSON數組或對象節點,則訪問此節點的所有值節點,對於對象節點,不包括字段名(鍵),只包括值,對於其他類型的節點,返回空迭代器。 |
boolean has(int index) | 檢查此節點是否為數組節點,並是否含有指定的索引。 |
boolean has(String fieldName) |
檢查此節點是否為 JSON 對象節點並包含指定屬性的值。 |
將 json 屬性的值轉為 java 數據類型 | |
int asInt() |
asInt():嘗試將此節點的值轉換為 int 類型,布爾值 false 轉換為 0,true 轉換為 1。如果不能轉換為 int(比如值是對象或數組等結構化類型),則返回默認值 0 ,不會引發異常。 asInt(int defaultValue):設置默認值 |
boolean asBoolean() |
嘗試將此節點的值轉換為 Java 布爾值,0以外的整數映射為true,0映射為false,字符串“true”和“false”映射到相應的值。 如果無法轉換為布爾值(包括對象和數組等結構化類型),則返回默認值 false,不會引發異常。 可以自己設置默認值。 |
asText(String defaultValue) String asText() |
如果節點是值節點(isValueNode 返回 true),則返回容器值的有效字符串表示形式,否則返回空字符串。 |
long asLong() long asLong(long defaultValue) |
與 asInt 同理 |
double asDouble() |
嘗試將此節點的值轉換為 double,布爾值轉換為0.0(false)和1.0(true),字符串使用默認的Java 語言浮點數解析規則進行解析。 如果表示不能轉換為 double(包括對象和數組等結構化類型),則返回默認值 0.0,不會引發異常。 |
BigInteger bigIntegerValue() | 返回此節點的整數值(BigDecimal),當且僅當此節點為數字時(isNumber}返回true)。 對於其他類型,返回 BigInteger.ZERO。 |
boolean booleanValue() | 用於訪問 JSON 布爾值(值文本“true”和“false”)的方法,對於其他類型,始終返回false |
BigDecimal decimalValue() | 返回此節點的浮點值 BigDecimal, 當且僅當此節點為數字時(isNumber 返回true),對於其他類型,返回 BigDecimal.ZERO |
double doubleValue() | 返回此節點的64位浮點(雙精度)值,當且僅當此節點為數字時(isNumber返回true),對於其他類型,返回0.0。 |
float floatValue() | 返回此節點的32位浮點值,當且僅當此節點為數字時(isNumber返回true),對於其他類型,返回0.0。 |
int intValue() long longValue() Number numberValue() short shortValue() String textValue() |
返回此節點的 int、long、Number、short、String 值。 |
ObjectNode 對象節點常用方法 | |
ObjectNode put(String fieldName, String v) |
1、將字段的值設置為指定的值,如果字段已經存在,則更新值,value 可以為 null. 2、其它 8 種基本數據類型以及 String、BigDecimal、BigInteger 都可以 put,但是沒有 Date 類型 3、Date 日期類型只能通過 Long 長整型設置 |
ArrayNode putArray(String fieldName) | 構造新的 ArrayNode 子節點,並將其作為此 ObjectNode 的字段添加。 |
ObjectNode putNull(String fieldName): | 為指定字段添加 null 值,put |
ObjectNode putObject(String fieldName) | 構造新的 ObjectNode 字節的,並將其作為此 ObjectNode 的字段添加。 |
替換與刪除元素 | |
JsonNode replace(String fieldName, JsonNode value) | 將特定屬性的值替換為傳遞的值,字段存在時更新,不存在時新增 |
JsonNode set(String fieldName, JsonNode value) | 設置指定屬性的值為 json 節點對象,字段存在時更新,不存在時新增,類似 replace 方法 |
JsonNode setAll(Map<String,? extends JsonNode> properties) | 同時設置多個 json 節點 |
JsonNode setAll(ObjectNode other) | 添加給定對象(other)的所有屬性,重寫這些屬性的任何現有值. |
ArrayNode withArray(String propertyName) | 將 json 節點轉為 json 數組對象 |
ObjectNode with(String propertyName) | 將 json 節點轉為 ObjectNode 對象 |
JsonNode remove(String fieldName) | 刪除指定的 key,返回被刪除的節點 |
ObjectNode remove(Collection<String> fieldNames) | 同時刪除多個字段 |
ObjectNode removeAll() | 刪除所有字段屬性 |
JsonNode without(String fieldName): | 刪除指定的 key,底層也是 remove |
ObjectNode without(Collection<String> fieldNames) | 同時刪除多個字段,底層也是 removeAll |
ArrayNode 數組節點常用方法 | |
ArrayNode add(String v) | 將指定的字符串值添加到此 json 數組的末尾,其它數據類型也是同理。 除了可以添加 String 類型,還有 Java 的 8 種基本數據類型,以及 BigDecimal、BigInteger、JsonNode 類型。 |
ArrayNode addAll(ArrayNode other) | 用於添加給定數組的所有子節點 |
ArrayNode addNull() | 該方法將在此數組節點的末尾添加 null 值。 |
ArrayNode addArray() | 構造新的 ArrayNode 子節點,並將其添加到此數組節點的末尾 |
ObjectNode addObject() | 構造一個新的 ObjectNode 字節的,並將其添加到此數組節點的末尾 |
API 演示源碼:/src/main/java/com/wmx/jackson/JsonNodeTest.java

package com.wmx.jackson; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.NumericNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Test; import java.io.IOException; import java.math.BigDecimal; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * {@link ArrayNode}、{@link ObjectNode}、{@link NumericNode} 等等都是 {@link JsonNode} 的子類 * * @author wangMaoXiong * @version 1.0 * @date 2020/7/16 16:57 */ @SuppressWarnings("all") public class JsonNodeTest { /** * JsonNodeFactory.instance: 創建單例的 JsonNodeFactory 工廠 * ObjectNode objectNode() : 構造空的 JSON 對象 * ObjectNode put(String fieldName, String v): 將字段的值設置為指定的字符串值,如果字段已經存在,則更新值 * ObjectNode put(String fieldName, int v):其它數據類型也是同理 * ArrayNode putArray(String fieldName):構造 ArrayNode 並將其作為此 ObjectNode 的字段添加。 * ObjectNode putNull(String fieldName): 為指定字段添加 null 值 * ArrayNode add(String v) :將指定的字符串值添加到此數組的末尾,其它數據類型也是同理。 */ @Test public void objectNode1() { JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance; ObjectNode objectNode = jsonNodeFactory.objectNode(); objectNode.put("name", "張三"); objectNode.put("age", 25); objectNode.putNull("marry"); ArrayNode arrayNode = objectNode.putArray("urls"); arrayNode.add("http://tomcat.org/tomcat.png#1"); arrayNode.add("http://tomcat.org/tomcat.png#2"); arrayNode.add("http://tomcat.org/tomcat.png#3"); //{"name":"張三","age":25,"marry":null,"urls":["http://tomcat.org/tomcat.png#1","http://tomcat.org/tomcat.png#2","http://tomcat.org/tomcat.png#3"]} System.out.println(objectNode.toString()); } @Test public void objectNode2() { JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance; ObjectNode objectNode_root = jsonNodeFactory.objectNode(); ArrayNode arrayNode = objectNode_root.putArray("notices"); ObjectNode objectNodeChild = jsonNodeFactory.objectNode(); objectNodeChild.put("title", "放假通知"); objectNodeChild.put("content", "寒假放假於本月3浩開始."); arrayNode.add(objectNodeChild); //{"notices":[{"title":"放假通知","content":"寒假放假於本月3浩開始."}]} System.out.println(objectNode_root); } /** * JsonNode replace(String fieldName, JsonNode value):將特定屬性的值替換為傳遞的值,字段存在時更新,不存在時新增 * JsonNode set(String fieldName, JsonNode value):設置指定屬性的值為 json 節點對象,字段存在時更新,不存在時新增,類似 replace 方法 * JsonNode setAll(Map<String,? extends JsonNode> properties):同時設置多個 json 節點 */ @Test public void objectNode3() { try { String json = "{\"notices\":[{\"title\":\"放假通知\",\"content\":\"寒假放假於本月3浩開始.\"}]}"; JsonNode jsonNode = new ObjectMapper().readTree(json); ObjectNode objectNode = (ObjectNode) jsonNode; ObjectNode node = JsonNodeFactory.instance.objectNode(); node.put("code", 200); objectNode.set("status", node); //{"notices":[{"title":"放假通知","content":"寒假放假於本月3浩開始."}],"status":{"code":200}} System.out.println(objectNode); } catch (IOException e) { e.printStackTrace(); } } /** * JsonNode setAll(ObjectNode other):添加給定對象(other)的所有屬性,重寫這些屬性的任何現有值 */ @Test public void objectNode4() { try { String json = "{\"notices\":[{\"title\":\"放假通知\",\"content\":\"寒假放假於本月3浩開始.\"}]}"; JsonNode jsonNode = new ObjectMapper().readTree(json); ObjectNode objectNode = (ObjectNode) jsonNode; ObjectNode node = JsonNodeFactory.instance.objectNode(); node.put("code", 200); objectNode.setAll(node); //{"notices":[{"title":"放假通知","content":"寒假放假於本月3浩開始."}],"code":200} System.out.println(objectNode); } catch (IOException e) { e.printStackTrace(); } } /** * JsonNode get(String fieldName): * 1、用於訪問對象節點的指定字段的值,如果此節點不是對象、或沒有指定字段名的值,或沒有這樣名稱的字段,則返回 null。 * boolean isArray(): 判斷此節點是否為 {@link ArrayNode} 數組節點 * int size():獲取數組節點的大小 * int asInt(): * 1、嘗試將此節點的值轉換為 int 類型,布爾值 false 轉換為 0,true 轉換為 1。 * 2、如果不能轉換為 int(比如值是對象或數組等結構化類型),則返回默認值 0 ,不會引發異常。 * String asText():如果節點是值節點(isValueNode返回true),則返回容器值的有效字符串表示形式,否則返回空字符串。 * 其它數據類型也是同理 */ @Test public void objectNode5() { try { String json = "{\"notices\":[{\"title\":\"停水\",\"day\":\"12\"},{\"title\":\"停電\",\"day\":\"32\"},{\"title\":\"停網\",\"day\":\"22\"}]}"; ObjectMapper objectMapper = new ObjectMapper(); ObjectNode jsonNode = (ObjectNode) objectMapper.readTree(json); JsonNode notices = jsonNode.get("notices"); if (notices != null && notices.isArray()) { for (int i = 0; i < notices.size(); i++) { JsonNode childNode = notices.get(i); String title = childNode.get("title").asText(); Integer day = childNode.get("day").asInt(); System.out.println((i + 1) + ":" + title + "\t" + day); } } } catch (IOException e) { e.printStackTrace(); } } /** * ArrayNode withArray(String propertyName): 將 json 節點轉為 json 數組對象 * ObjectNode with(String propertyName):將 json 節點轉為 ObjectNode 對象 */ @Test public void objectNode6() { try { String json = "{\"notices\":[{\"title\":\"放假通知\",\"content\":\"寒假放假於本月3浩開始.\"}]}"; JsonNode jsonNode = new ObjectMapper().readTree(json); ObjectNode objectNode = (ObjectNode) jsonNode; ArrayNode arrayNode = objectNode.withArray("notices"); for (int i = 0; i < arrayNode.size(); i++) { //{"title":"放假通知","content":"寒假放假於本月3浩開始."} JsonNode node = arrayNode.get(i); System.out.println(node); } } catch (IOException e) { e.printStackTrace(); } } /** * JsonNode remove(String fieldName):刪除指定的 key,返回被刪除的節點 * JsonNode without(String fieldName): * ObjectNode remove(Collection<String> fieldNames):同時刪除多個字段 * ObjectNode without(Collection<String> fieldNames):同時刪除多個字段 * ObjectNode removeAll(): 刪除所有字段屬性 */ @Test public void objectNode7() { try { String json = "{\"notices\":[{\"title\":\"放假通知\",\"content\":\"寒假放假於本月3浩開始.\"}]}"; JsonNode jsonNode = new ObjectMapper().readTree(json); ObjectNode objectNode = (ObjectNode) jsonNode; JsonNode remove = objectNode.remove("notices"); System.out.println(remove);//[{"title":"放假通知","content":"寒假放假於本月3浩開始."}] System.out.println(objectNode);//{} } catch (IOException e) { e.printStackTrace(); } } /** * ObjectNode deepCopy():json 節點對象深度復制,相當於克隆 * Iterator<String> fieldNames(): 獲取 json 對象中的所有 key */ @Test public void objectNode8() { try { String json = "{\"title\":\"放假通知\",\"content\":\"寒假放假於本月3浩開始.\"}"; JsonNode jsonNode = new ObjectMapper().readTree(json); ObjectNode objectNode = (ObjectNode) jsonNode; ObjectNode deepCopy = objectNode.deepCopy(); deepCopy.put("summary", "同意"); System.out.println(objectNode);//{"title":"放假通知","content":"寒假放假於本月3浩開始."} System.out.println(deepCopy);//{"title":"放假通知","content":"寒假放假於本月3浩開始.","summary":"同意"} Iterator<String> fieldNames = deepCopy.fieldNames(); while (fieldNames.hasNext()) { String next = fieldNames.next(); System.out.println(next + "=" + deepCopy.get(next)); } } catch (IOException e) { e.printStackTrace(); } } @Test public void objectNode9() { Map<String, Object> dataMap = new HashMap<>(); dataMap.put("code", 200); dataMap.put("msg", "成功"); ObjectNode objectNode = JsonNodeFactory.instance.objectNode(); objectNode.putPOJO("data", dataMap); System.out.println(objectNode); JsonNode jsonNode = objectNode.get("data"); } /** * double asDouble(): 嘗試將此節點的值轉換為 double,布爾值轉換為0.0(false)和1.0(true),字符串使用默認的Java 語言浮點數解析規則進行解析。 * 如果表示不能轉換為 double(包括對象和數組等結構化類型),則返回默認值 0.0,不會引發異常。 * BigDecimal decimalValue() :返回此節點的浮點值 BigDecimal, 當且僅當此節點為數字時(isNumber 返回true),對於其他類型,返回 BigDecimal.ZERO */ @Test public void test10() { ObjectNode objectNode = JsonNodeFactory.instance.objectNode(); objectNode.put("id", 1000); objectNode.put("salay", 15000.456); double salay = objectNode.get("salay").asDouble(); BigDecimal bigDecimal = objectNode.get("salay").decimalValue(); System.out.println(salay + "," + bigDecimal);//15000.456,15000.456 } /** * boolean has(int index):檢查此節點是否為數組節點,並是否含有指定的索引。 * boolean has(String fieldName):檢查此節點是否為 JSON 對象節點並包含指定屬性的值。 */ @Test public void test11() { ArrayNode arrayNode = JsonNodeFactory.instance.arrayNode(); arrayNode.add(12).add("中國").addNull().add(345.5667); System.out.println(arrayNode);//[12,"中國",null,345.5667] System.out.println(arrayNode.has(1));//true System.out.println(arrayNode.has(2));//true System.out.println(arrayNode.has(4));//false } /** * Iterator<JsonNode> elements():如果該節點是JSON數組或對象節點,則訪問此節點的所有值節點 * 對於對象節點,不包括字段名(鍵),只包括值,對於其他類型的節點,返回空迭代器。 */ @Test public void test12() { try { String json = "{\"title\":\"放假通知\",\"content\":\"寒假放假於本月3浩開始.\",\"id\":23400}"; JsonNode jsonNode = new ObjectMapper().readTree(json); Iterator<JsonNode> elements = jsonNode.elements(); while (elements.hasNext()) { JsonNode next = elements.next(); //"放假通知" "寒假放假於本月3浩開始." 23400 System.out.print(next + " "); } } catch (IOException e) { e.printStackTrace(); } } /** * ArrayNode addAll(ArrayNode other): 用於添加給定數組的所有子節點 */ @Test public void test13() { try { String json = "[{\"title\":\"放假通知\",\"content\":\"寒假放假於本月3浩開始.\"}]"; JsonNode jsonNode = new ObjectMapper().readTree(json); ArrayNode rootArrayNode = JsonNodeFactory.instance.arrayNode(); rootArrayNode.add(1000); if (jsonNode.isArray()) { ArrayNode arrayNode = (ArrayNode) jsonNode; rootArrayNode.addAll(arrayNode); } //[1000,{"title":"放假通知","content":"寒假放假於本月3浩開始."}] System.out.println(rootArrayNode); } catch (IOException e) { e.printStackTrace(); } } /** * ArrayNode addNull() :該方法將在此數組節點的末尾添加空值。 */ @Test public void test14() { try { String json = "[{\"title\":\"放假通知\",\"content\":\"寒假放假於本月3浩開始.\"}]"; JsonNode jsonNode = new ObjectMapper().readTree(json); if (jsonNode.isArray()) { ArrayNode arrayNode = (ArrayNode) jsonNode; arrayNode.addNull(); //[{"title":"放假通知","content":"寒假放假於本月3浩開始."},null] System.out.println(arrayNode); } } catch (IOException e) { e.printStackTrace(); } } /** * ArrayNode addArray(): 構造新的 ArrayNode 節點,並將其添加到此數組節點的末尾 */ @Test public void test15() { try { String json = "[{\"title\":\"放假通知\",\"content\":\"寒假放假於本月3浩開始.\"}]"; JsonNode jsonNode = new ObjectMapper().readTree(json); if (jsonNode.isArray()) { ArrayNode arrayNode = (ArrayNode) jsonNode; ArrayNode addArray = arrayNode.addArray(); addArray.add(31.4F); addArray.add("優秀"); //[{"title":"放假通知","content":"寒假放假於本月3浩開始."},[31.4,"優秀"]] System.out.println(arrayNode); //[31.4,"優秀"] System.out.println(addArray); } } catch (IOException e) { e.printStackTrace(); } } /** * ObjectNode putObject(String fieldName):構造新的 ObjectNode 字節的,並將其作為此 ObjectNode 的字段添加。 */ @Test public void test16() { try { String json = "{\"title\":\"放假通知\",\"content\":\"寒假放假於本月3浩開始.\"}"; JsonNode jsonNode = new ObjectMapper().readTree(json); if (jsonNode.isObject()) { ObjectNode objectNode = (ObjectNode) jsonNode; ObjectNode persons = objectNode.putObject("person"); persons.put("name", "張三"); persons.put("age", 34); //{"title":"放假通知","content":"寒假放假於本月3浩開始.","person":{"name":"張三","age":34}} System.out.println(objectNode); } } catch (IOException e) { e.printStackTrace(); } } }
Jsonson 注解設置 POJO 屬性
1、ObjectMapper 序列化 POJO 對象為 json 字符串時,Date 日期類型默認會轉為 long 長整型,json 字符串反序列化為 POJO 時自動將長整型的日期轉為 Date 類型。
2、Map 對象序列化為 json 字符串時,Map 中的日期值也會默認轉為 long 長整型, ObjectMapper.readValue(String content, Class<T> valueType):反序列化為 Map 對象時,長整型的日期仍舊是長整型,不會轉回 Date。ObjectMapper.readTree(String content) 反序列化為 json 節點時,原來 Map 中的長整型的日期也會是長整型。
3、JsonNode 節點對象 put 數據時,有 8 種基本數據類型以及 String、BigDecimal、BigInteger,但是沒有 Date 類型,所以日期類型只能通過 Long 長整型設置,但是轉 POJO 對象時仍然會自動轉為 Date 類型。
4、Google 的 gson 默認不會序列化對象中值為 null 的字段,而 jackson 則不管值是否為 null,都會序列化。
5、@JsonFormat 注解加到指定對象的屬性上可以指定日期序列化的格式。
6、JsonInclude(JsonInclude.Include.NON_NULL) 添加到 POJO 對象上,表示對值為 null 的屬性不進行序列化。
參考文章:https://blog.csdn.net/wangmx1993328/article/details/88598625