利用Jackson解析JSON的詳細實現(xiàn)教程
JSON 對于開發(fā)者并不陌生,如今的 WEB 服務(wù)、移動應(yīng)用、甚至物聯(lián)網(wǎng)大多都是以 JSON 作為數(shù)據(jù)交換的格式。學(xué)習(xí) JSON 格式的操作工具對開發(fā)者來說是必不可少的。這篇文章將介紹如何使用 Jackson 開源工具庫對 JSON 進行常見操作。
JSON logo
JSON 介紹
什么是 JSON ?JSON 是 ”JavaScript Object Notation“ 的縮寫,JSON 是一種基于文本的格式,可以把它理解為是一個結(jié)構(gòu)化的數(shù)據(jù),這個結(jié)構(gòu)化數(shù)據(jù)中可以包含鍵值映射、嵌套對象以及數(shù)組等信息。
{ ??"array":?[ ????1, ????2, ????3 ??], ??"boolean":?true, ??"color":?"gold", ??"null":?null, ??"number":?123, ??"object":?{ ????"a":?"b", ????"c":?"d" ??}, ??"string":?"www.wdbyte.com" }
Jackson 介紹
Jackson 和 FastJson 一樣,是一個 Java 語言編寫的,可以進行 JSON 處理的開源工具庫,Jackson 的使用非常廣泛,Spring 框架默認使用 Jackson 進行 JSON 處理。
Jackson 有三個核包,分別是 Streaming、Databid、Annotations,通過這些包可以方便的對 JSON 進行操作。
• Streaming[1] 在 jackson-core
模塊。定義了一些流處理相關(guān)的 API 以及特定的 JSON 實現(xiàn)。
• Annotations[2] 在 jackson-annotations
模塊,包含了 Jackson 中的注解。
• Databind[3] 在 jackson-databind
模塊, 在 Streaming
包的基礎(chǔ)上實現(xiàn)了數(shù)據(jù)綁定,依賴于 Streaming
和 Annotations
包。
得益于 Jackson 高擴展性的設(shè)計,有很多常見的文本格式以及工具都有對 Jackson 的相應(yīng)適配,如 CSV、XML、YAML 等。
Jackson Maven 依賴
在使用 Jackson 時,大多數(shù)情況下我們只需要添加 jackson-databind
依賴項,就可以使用 Jackson 功能了,它依賴了下面兩個包。
jackson-databind 依賴
• com.fasterxml.jackson.core:jackson-annotations
• com.fasterxml.jackson.core:jackson-core
<dependency> ????<groupId>com.fasterxml.jackson.core</groupId> ????<artifactId>jackson-databind</artifactId> ????<version>2.13.3</version> </dependency>
為了方便這篇文章后續(xù)的代碼演示,我們同時引入 Junit 進行單元測試和 Lombok 以減少 Get/Set 的代碼編寫。
<dependency> ????<groupId>org.junit.jupiter</groupId> ????<artifactId>junit-jupiter</artifactId> ????<version>5.8.2</version> ????<scope>test</scope> </dependency> <dependency> ????<groupId>org.projectlombok</groupId> ????<artifactId>lombok</artifactId> ????<version>1.18.22</version> </dependency>
ObjectMapper 對象映射器
ObjectMapper
是 Jackson 庫中最常用的一個類,使用它可以進行 Java 對象和 JSON 字符串之間快速轉(zhuǎn)換。如果你用過 FastJson,那么 Jackson 中的 ObjectMapper
就如同 FastJson 中的 JSON 類。
這個類中有一些常用的方法:
• readValue()
方法可以進行 JSON 的反序列化操作,比如可以將字符串、文件流、字節(jié)流、字節(jié)數(shù)組等將常見的內(nèi)容轉(zhuǎn)換成 Java 對象。
• writeValue()
方法可以進行 JSON 的序列化操作,可以將 Java 對象轉(zhuǎn)換成 JSON 字符串。
大多數(shù)情況下,ObjectMapper
的工作原理是通過 Java Bean 對象的 Get/Set 方法進行轉(zhuǎn)換時映射的,所以正確編寫 Java 對象的 Get/Set 方法尤為重要,不過 ObjectMapper
也提供了諸多配置,比如可以通過配置或者注解的形式對 Java 對象和 JSON 字符串之間的轉(zhuǎn)換過程進行自定義。這些在下面部分都會介紹到。
Jackson JSON 基本操作
Jackson 作為一個 Java 中的 JSON 工具庫,處理 JSON 字符串和 Java 對象是它最基本最常用的功能,下面通過一些例子來演示其中的用法。
Jackson JSON 序列化
編寫一個 Person 類,定義三個屬性,名稱、年齡以及技能。
/** ?*?@author?https://www.wdbyte.com ?*/ @Data public?class?Person?{ ????private?String?name; ????private?Integer?age; ????private?List<String>?skillList; }
將 Java 對象轉(zhuǎn)換成 JSON 字符串。
import?java.util.Arrays; import?com.fasterxml.jackson.core.JsonProcessingException; import?com.fasterxml.jackson.databind.ObjectMapper; import?org.junit.jupiter.api.Assertions; import?org.junit.jupiter.api.Test; /** ?*?@author?https://www.wdbyte.com ?*/ class?PersonTest?{ ????ObjectMapper?objectMapper?=?new?ObjectMapper(); ????@Test ????void?pojoToJsonString()?throws?JsonProcessingException?{ ????????Person?person?=?new?Person(); ????????person.setName("aLng"); ????????person.setAge(27); ????????person.setSkillList(Arrays.asList("java",?"c++")); ????????String?json?=?objectMapper.writeValueAsString(person); ????????System.out.println(json); ????????String?expectedJson?=?"{\"name\":\"aLng\",\"age\":27,\"skillList\":[\"java\",\"c++\"]}"; ????????Assertions.assertEquals(json,?expectedJson); ????} }
輸出的 JSON 字符串:
{"name":"aLng","age":27,"skillList":["java","c++"]}
Jackson 甚至可以直接把序列化后的 JSON 字符串寫入文件或者讀取成字節(jié)數(shù)組。
mapper.writeValue(new?File("result.json"),?myResultObject); //?或者 byte[]?jsonBytes?=?mapper.writeValueAsBytes(myResultObject); //?或者 String?jsonString?=?mapper.writeValueAsString(myResultObject);
Jackson JSON 反序列化
直接貼出代碼:
package?com.wdbyte.jackson; import?com.fasterxml.jackson.core.JsonProcessingException; import?com.fasterxml.jackson.databind.ObjectMapper; import?org.junit.jupiter.api.Assertions; import?org.junit.jupiter.api.Test; /** ?*?@author?https://www.wdbyte.com ?*/ class?PersonTest?{ ????ObjectMapper?objectMapper?=?new?ObjectMapper(); ????@Test ????void?jsonStringToPojo()?throws?JsonProcessingException?{ ????????String?expectedJson?=?"{\"name\":\"aLang\",\"age\":27,\"skillList\":[\"java\",\"c++\"]}"; ????????Person?person?=?objectMapper.readValue(expectedJson,?Person.class); ????????System.out.println(person); ????????Assertions.assertEquals(person.getName(),?"aLang"); ????????Assertions.assertEquals(person.getSkillList().toString(),?"[java,?c++]"); ????} }
輸出結(jié)果:
Person(name=aLang, age=27, skillList=[java, c++])
上面的例子演示了如何使用 Jackson 把一個 JSON 字符串反序列化成 Java 對象,其實 Jackson 對文件中的 JSON 字符串、字節(jié)形式的 JSON 字符串反序列化同樣簡單。
比如先準(zhǔn)備了一個 JSON 內(nèi)容文件 Person.json。
{ ??"name":?"aLang", ??"age":?27, ??"skillList":?[ ????"java", ????"c++" ??] }
下面進行讀取轉(zhuǎn)換。
ObjectMapper?objectMapper?=?new?ObjectMapper(); @Test void?testJsonFilePojo()?throws?IOException?{ ????File?file?=?new?File("src/Person.json"); ????Person?person?=?objectMapper.readValue(file,?Person.class); ??????//?或者 ????//?person?=?mapper.readValue(new?URL("http://some.com/api/entry.json"),?MyValue.class); ????System.out.println(person); ????Assertions.assertEquals(person.getName(),?"aLang"); ????Assertions.assertEquals(person.getSkillList().toString(),?"[java,?c++]"); }
同樣輸出了 Person 內(nèi)容。
Person(name=aLang, age=27, skillList=[java, c++])
JSON 轉(zhuǎn) List
上面演示 JSON 字符串都是單個對象的,如果 JSON 是一個對象列表那么使用 Jackson 該怎么處理呢?
已經(jīng)存在一個文件 PersonList.json
.
[ ??{ ????"name":?"aLang", ????"age":?27, ????"skillList":?[ ??????"java", ??????"c++" ????] ??}, ??{ ????"name":?"darcy", ????"age":?26, ????"skillList":?[ ??????"go", ??????"rust" ????] ??} ]
讀取它然后轉(zhuǎn)換成 List<Person>
。
ObjectMapper?objectMapper?=?new?ObjectMapper(); @Test void?fileToPojoList()?throws?IOException?{ ????File?file?=?new?File("src/EmployeeList.json"); ????List<Person>?personList?=?objectMapper.readValue(file,?new?TypeReference<List<Person>>()?{}); ????for?(Person?person?:?personList)?{ ????????System.out.println(person); ????} ????Assertions.assertEquals(personList.size(),?2); ????Assertions.assertEquals(personList.get(0).getName(),?"aLang"); ????Assertions.assertEquals(personList.get(1).getName(),?"darcy"); }
可以輸出對象內(nèi)容:
Person(name=aLang, age=27, skillList=[java, c++])
Person(name=darcy, age=26, skillList=[go, rust])
JSON 轉(zhuǎn) Map
JSON 轉(zhuǎn) Map 在我們沒有一個對象的 Java 對象時十分實用,下面演示如何使用 Jackson 把 JSON 文本轉(zhuǎn)成 Map 對象。
ObjectMapper?objectMapper?=?new?ObjectMapper(); @Test void?jsonStringToMap()?throws?IOException?{ ????String?expectedJson?=?"{\"name\":\"aLang\",\"age\":27,\"skillList\":[\"java\",\"c++\"]}"; ????Map<String,?Object>?employeeMap?=?objectMapper.readValue(expectedJson,?new?TypeReference<Map>()?{}); ????System.out.println(employeeMap.getClass()); ????for?(Entry<String,?Object>?entry?:?employeeMap.entrySet())?{ ????????System.out.println(entry.getKey()?+?":"?+?entry.getValue()); ????} ????Assertions.assertEquals(employeeMap.get("name"),?"aLang"); }
可以看到 Map 的輸出結(jié)果:
class java.util.LinkedHashMap
name:aLang
age:27
skillList:[java, c++]
Jackson 忽略字段
如果在進行 JSON 轉(zhuǎn) Java 對象時,JSON 中出現(xiàn)了 Java 類中不存在的屬性,那么在轉(zhuǎn)換時會遇到 com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException
異常。
使用 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
可以忽略不存在的屬性。
ObjectMapper?objectMapper?=?new?ObjectMapper(); @Test void?jsonStringToPojoIgnoreProperties()?throws?IOException?{ ????//?UnrecognizedPropertyException ????String?json?=?"{\"yyy\":\"xxx\",\"name\":\"aLang\",\"age\":27,\"skillList\":[\"java\",\"c++\"]}"; ????objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,?false); ????Person?person?=?objectMapper.readValue(json,?Person.class); ??????System.out.printf(person.toString()); ????Assertions.assertEquals(person.getName(),?"aLang"); ????Assertions.assertEquals(person.getSkillList().toString(),?"[java,?c++]"); }
正常輸出:
Person(name=aLang, age=27, skillList=[java, c++])
Jackson 日期格式化
在 Java 8 之前我們通常使用 java.util.Date
類來處理時間,但是在 Java 8 發(fā)布時引入了新的時間類 java.time.LocalDateTime
. 這兩者在 Jackson 中的處理略有不同。
先創(chuàng)建一個有兩種時間類型屬性的 Order 類。
package?com.wdbyte.jackson; import?java.time.LocalDateTime; import?java.util.Date; import?com.fasterxml.jackson.annotation.JsonFormat; import?lombok.AllArgsConstructor; import?lombok.Data; import?lombok.NoArgsConstructor; /** ?*?@author?https://www.wdbyte.com ?*/ @Data @AllArgsConstructor @NoArgsConstructor public?class?Order?{ ?? ????private?Integer?id; ????private?Date?createTime; ????private?LocalDateTime?updateTime; }
Date 類型
下面我們新建一個測試用例來測試兩種時間類型的 JSON 轉(zhuǎn)換。
package?com.wdbyte.jackson; import?java.time.LocalDateTime; import?java.util.Date; import?com.fasterxml.jackson.core.JsonProcessingException; import?com.fasterxml.jackson.databind.ObjectMapper; import?org.junit.jupiter.api.Assertions; import?org.junit.jupiter.api.Test; /** ?*?@author?https://www.wdbyte.com ?*/ class?OrderTest?{ ????ObjectMapper?objectMapper?=?new?ObjectMapper(); ????@Test ????void?testPojoToJson0()?throws?JsonProcessingException?{ ????????Order?order?=?new?Order(1,?new?Date(),?null); ????????String?json?=?objectMapper.writeValueAsString(order); ????????System.out.println(json); ????????order?=?objectMapper.readValue(json,?Order.class); ????????System.out.println(order.toString()); ????????Assertions.assertEquals(order.getId(),?1); ????} }
在這個測試代碼中,我們只初始化了 Date 類型的時間,下面是輸出的結(jié)果:
{"id":1,"createTime":1658320852395,"updateTime":null}
Order(id=1, createTime=Wed Jul 20 20:40:52 CST 2022, updateTime=null)
可以看到正常的進行了 JSON 的序列化與反序列化,但是 JSON 中的時間是一個時間戳格式,可能不是我們想要的。
LocalDateTime 類型
為什么沒有設(shè)置 LocalDateTime
類型的時間呢?因為默認情況下進行 LocalDateTime 類的 JSON 轉(zhuǎn)換會遇到報錯。
/** ?*?@author?https://www.wdbyte.com ?*/ class?OrderTest?{ ????ObjectMapper?objectMapper?=?new?ObjectMapper(); ????@Test ????void?testPojoToJson()?throws?JsonProcessingException?{ ????????Order?order?=?new?Order(1,?new?Date(),?LocalDateTime.now()); ????????String?json?=?objectMapper.writeValueAsString(order); ????????System.out.println(json); ????????order?=?objectMapper.readValue(json,?Order.class); ????????System.out.println(order.toString()); ????????Assertions.assertEquals(order.getId(),?1); ????} }
運行后會遇到報錯:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Java 8 date/time type `java.time.LocalDateTime` not supported by default:
add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
to enable handling (through reference chain: com.wdbyte.jackson.Order["updateTime"])
這里我們需要添加相應(yīng)的數(shù)據(jù)綁定支持包。
添加依賴:
<dependency> ????<groupId>com.fasterxml.jackson.datatype</groupId> ????<artifactId>jackson-datatype-jsr310</artifactId> ????<version>2.13.3</version> </dependency>
然后在定義 ObjectMapper 時通過 findAndRegisterModules()
方法來注冊依賴。
import?java.time.LocalDateTime; import?java.util.Date; import?com.fasterxml.jackson.core.JsonProcessingException; import?com.fasterxml.jackson.databind.ObjectMapper; import?org.junit.jupiter.api.Assertions; import?org.junit.jupiter.api.Test; /** ?*?@author?https://www.wdbyte.com ?*/ class?OrderTest?{ ????ObjectMapper?objectMapper?=?new?ObjectMapper().findAndRegisterModules(); ????@Test ????void?testPojoToJson()?throws?JsonProcessingException?{ ????????Order?order?=?new?Order(1,?new?Date(),?LocalDateTime.now()); ????????String?json?=?objectMapper.writeValueAsString(order); ????????System.out.println(json); ????????order?=?objectMapper.readValue(json,?Order.class); ????????System.out.println(order.toString()); ????????Assertions.assertEquals(order.getId(),?1); ????} }
運行可以得到正常序列化與反序列化日志,不過序列化后的時間格式依舊奇怪。
{"id":1,"createTime":1658321191562,"updateTime":[2022,7,20,20,46,31,567000000]}
Order(id=1, createTime=Wed Jul 20 20:46:31 CST 2022, updateTime=2022-07-20T20:46:31.567)
時間格式化
通過在字段上使用注解 @JsonFormat
來自定義時間格式。
import?java.time.LocalDateTime; import?java.util.Date; import?com.fasterxml.jackson.annotation.JsonFormat; import?lombok.AllArgsConstructor; import?lombok.Data; import?lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public?class?Order?{ ????private?Integer?id; ????@JsonFormat(pattern?=?"yyyy-MM-dd?HH:mm:ss",?timezone?=?"Asia/Shanghai") ????private?Date?createTime; ????@JsonFormat(pattern?=?"yyyy-MM-dd?HH:mm:ss",?timezone?=?"Asia/Shanghai") ????private?LocalDateTime?updateTime; }
再次運行上面的列子可以得到時間格式化后的 JSON 字符串。
{"id":1,"createTime":"2022-07-20 20:49:46","updateTime":"2022-07-20 20:49:46"}
Order(id=1, createTime=Wed Jul 20 20:49:46 CST 2022, updateTime=2022-07-20T20:49:46)
Jackson 常用注解
@JsonIgnore
使用 @JsonIgnore
可以忽略某個 Java 對象中的屬性,它將不參與 JSON 的序列化與反序列化。
示例:
package?com.wdbyte.jackson; import?com.fasterxml.jackson.annotation.JsonIgnore; import?lombok.Data; /** ?*?@author?https://www.wdbyte.com ?*/ @Data public?class?Cat?{ ????private?String?name; ????@JsonIgnore ????private?Integer?age; }
編寫單元測試類。
package?com.wdbyte.jackson; import?com.fasterxml.jackson.core.JsonProcessingException; import?com.fasterxml.jackson.databind.ObjectMapper; import?org.junit.jupiter.api.Assertions; import?org.junit.jupiter.api.Test; /** ?*?@author?https://www.wdbyte.com ?*/ class?CatTest?{ ????ObjectMapper?objectMapper?=?new?ObjectMapper(); ????@Test ????void?testPojoToJson()?throws?JsonProcessingException?{ ????????Cat?cat?=?new?Cat(); ????????cat.setName("Tom"); ????????cat.setAge(2); ????????String?json?=?objectMapper.writeValueAsString(cat); ????????System.out.println(json); ????????Assertions.assertEquals(json,?"{\"name\":\"Tom\"}"); ????????cat?=?objectMapper.readValue(json,?Cat.class); ????????Assertions.assertEquals(cat.getName(),?"Tom"); ????????Assertions.assertEquals(cat.getAge(),?null); ????} }
輸出結(jié)果中 age
屬性為 null
。
{"name":"Tom"}
@JsonGetter
使用 @JsonGetter
可以在對 Java 對象進行 JSON 序列化時自定義屬性名稱。
import?com.fasterxml.jackson.annotation.JsonGetter; import?com.fasterxml.jackson.annotation.JsonIgnore; import?lombok.Data; /** ?*?@author?https://www.wdbyte.com ?*/ @Data public?class?Cat?{ ????private?String?name; ????private?Integer?age; ????@JsonGetter(value?=?"catName") ????public?String?getName()?{ ????????return?name; ????} }
編寫單元測試類進行測試。
import?com.fasterxml.jackson.core.JsonProcessingException; import?com.fasterxml.jackson.databind.ObjectMapper; import?org.junit.jupiter.api.Assertions; import?org.junit.jupiter.api.Test; /** ?*?@author?https://www.wdbyte.com ?*/ class?CatTest?{ ????ObjectMapper?objectMapper?=?new?ObjectMapper(); ????@Test ????void?testPojoToJson2()?throws?JsonProcessingException?{ ????????Cat?cat?=?new?Cat(); ????????cat.setName("Tom"); ????????cat.setAge(2); ????????String?json?=?objectMapper.writeValueAsString(cat); ????????System.out.println(json); ????????Assertions.assertEquals(json,?"{\"age\":2,\"catName\":\"Tom\"}"); ????} }
輸出結(jié)果,name
已經(jīng)設(shè)置成了 catName
:
{"age":2,"catName":"Tom"}
@JsonSetter
使用 @JsonSetter
可以在對 JSON 進行反序列化時設(shè)置 JSON 中的 key 與 Java 屬性的映射關(guān)系。
package?com.wdbyte.jackson; import?com.fasterxml.jackson.annotation.JsonGetter; import?com.fasterxml.jackson.annotation.JsonIgnore; import?com.fasterxml.jackson.annotation.JsonSetter; import?lombok.Data; /** ?*?@author?https://www.wdbyte.com ?*?@date?2022/07/17 ?*/ @Data public?class?Cat?{ ????@JsonSetter(value?=?"catName") ????private?String?name; ????private?Integer?age; ????@JsonGetter(value?=?"catName") ????public?String?getName()?{ ????????return?name; ????} }
編寫單元測試類進行測試。
import?com.fasterxml.jackson.core.JsonProcessingException; import?com.fasterxml.jackson.databind.ObjectMapper; import?org.junit.jupiter.api.Assertions; import?org.junit.jupiter.api.Test; /** ?*?@author?https://www.wdbyte.com ?*/ class?CatTest?{ ????ObjectMapper?objectMapper?=?new?ObjectMapper(); ????@Test ????void?testPojoToJson2()?throws?JsonProcessingException?{ ????????String?json?=?"{\"age\":2,\"catName\":\"Tom\"}"; ????????Cat?cat?=?objectMapper.readValue(json,?Cat.class); ????????System.out.println(cat.toString()); ????????Assertions.assertEquals(cat.getName(),?"Tom"); ????} }
輸出結(jié)果:
Cat(name=Tom, age=2)
@JsonAnySetter
使用 @JsonAnySetter
可以在對 JSON 進行反序列化時,對所有在 Java 對象中不存在的屬性進行邏輯處理,下面的代碼演示把不存在的屬性存放到一個 Map 集合中。
import?java.util.Map; import?com.fasterxml.jackson.annotation.JsonAnyGetter; import?com.fasterxml.jackson.annotation.JsonAnySetter; import?com.google.common.collect.Maps; import?lombok.AllArgsConstructor; import?lombok.Data; import?lombok.NoArgsConstructor; /** ?*?@author?https://www.wdbyte.com ?*/ @Data @AllArgsConstructor @NoArgsConstructor public?class?Student?{ ????private?String?name; ????private?Integer?age; ????private?Map<String,?Object>?diyMap?=?new?HashMap<>(); ????@JsonAnySetter ????public?void?otherField(String?key,?String?value)?{ ????????this.diyMap.put(key,?value); ????} }
編寫單元測試用例。
import?java.util.HashMap; import?java.util.Map; import?com.fasterxml.jackson.core.JsonProcessingException; import?com.fasterxml.jackson.databind.ObjectMapper; import?org.junit.jupiter.api.Assertions; import?org.junit.jupiter.api.Test; /** ?*?@author?https://www.wdbyte.com ?*/ class?StudentTest?{ ????private?ObjectMapper?objectMapper?=?new?ObjectMapper(); ????@Test ????void?testJsonToPojo()?throws?JsonProcessingException?{ ????????Map<String,?Object>?map?=?new?HashMap<>(); ????????map.put("name",?"aLang"); ????????map.put("age",?18); ????????map.put("skill",?"java"); ????????String?json?=?objectMapper.writeValueAsString(map); ????????System.out.println(json); ????????Student?student?=?objectMapper.readValue(json,?Student.class); ????????System.out.println(student); ????????Assertions.assertEquals(student.getDiyMap().get("skill"),?"java"); ????} }
輸出結(jié)果中可以看到 JSON 中的 skill
屬性因為不在 Java 類 Student
中,所以被放到了 diyMap
集合。
{"skill":"java","name":"aLang","age":18}
Student(name=aLang, age=18, diyMap={skill=java})
@JsonAnyGetter
使用 @JsonAnyGetter
可以在對 Java 對象進行序列化時,使其中的 Map 集合作為 JSON 中屬性的來源。下面做個示例。
import?java.util.HashMap; import?java.util.Map; import?com.fasterxml.jackson.annotation.JsonAnyGetter; import?com.fasterxml.jackson.annotation.JsonAnySetter; import?com.google.common.collect.Maps; import?lombok.AllArgsConstructor; import?lombok.Data; import?lombok.Getter; import?lombok.NoArgsConstructor; import?lombok.Setter; import?lombok.ToString; /** ?*?@author?https://www.wdbyte.com ?*/ @ToString @AllArgsConstructor @NoArgsConstructor public?class?Student?{ ????@Getter ????@Setter ????private?String?name; ????@Getter ????@Setter ????private?Integer?age; ?? ????@JsonAnyGetter ????private?Map<String,?Object>?initMap?=?new?HashMap()?{{ ????????put("a",?111); ????????put("b",?222); ????????put("c",?333); ????}}; }
編寫單元測試用例。
class?StudentTest?{ ????private?ObjectMapper?objectMapper?=?new?ObjectMapper(); ????@Test ????void?testPojoToJsonTest()?throws?JsonProcessingException?{ ????????Student?student?=?new?Student(); ????????student.setName("aLang"); ????????student.setAge(20); ????????String?json?=?objectMapper.writeValueAsString(student); ????????System.out.println(json); ?????? ???????Assertions.assertEquals(json,"{\"name\":\"aLang\",\"age\":20,\"a\":111,\"b\":222,\"c\":333}"); ????} }
輸出結(jié)果:
{"name":"aLang","age":20,"a":111,"b":222,"c":333}
Jackson 總結(jié)
• Jackson 是 Java 中比較流量的 JSON 處理庫之一,它是 Spring 的默認 JSON 工具。
• Jackson 主要有三個模塊組成,Streaming API 、Annotations 和 Data Binding 。
• Jackson 中的 ObjectMapper 類十分強大,可以進行 JSON 相關(guān)處理,同時可以結(jié)合注釋以及配置進行自定義轉(zhuǎn)換邏輯。
• Jackson 擴展性很好,如 CSV、XML、YAML 格式處理都對 Jackson 有相應(yīng)的適配等。
到此這篇關(guān)于利用Jackson解析JSON的詳細實現(xiàn)教程的文章就介紹到這了,更多相關(guān)Jackson解析JSON內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Springboot打成JAR包后讀取外部配置文件的問題
這篇文章主要介紹了關(guān)于Springboot打成JAR包后讀取外部配置文件的問題,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11Java中的使用及連接Redis數(shù)據(jù)庫(附源碼)
這篇文章主要介紹了Java中的使用及連接Redis數(shù)據(jù)庫(附源碼),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09