Json 全稱是 JavaScript Object Notation,是一種輕量級的數據交換格式,采用完全獨立於編程語言的文本格式來存儲和表示數據。它易於閱讀和編寫,同時也易於計算機解析和生成,並能夠有效的提升網絡傳輸效率,簡潔清晰的層次結構,使得 JSON 成為目前主流的數據交換語言。
本篇博客主要介紹 Java 使用第三方 Jackson 的 jar 包,實現 Java Bean 對象與 Json 字符串之間的數據轉換,以及在不使用 Java Bean 對象作為轉換目標的情況下,讀取 Json 字段獲取數據的實現方式。在博客的末尾會提供源代碼。
Jackson 的官網地址:https://github.com/codehaus/jackson
一、搭建示例工程
新建一個 maven 工程,並導入 Jackson 的 jar 包。
Jackson 的 jar 包一共有 3 個,分別為:
jackson-core:這個最底層核心 jar 包,提供基於"流模式"解析的相關 API,其 jar 包地址為:
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
jackson-annotations:這個是注解包,提供標准注解功能,其 jar 包地址為:
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
jackson-databind:這個數據綁定包, 提供基於【對象綁定】解析的相關 API和【樹模型"】解析的相關 API,其 jar 包地址:
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
由於 jackson-databind 依賴 jackson-core 和 jackson-annotations,當我們使用 maven 導入 jackson-databind 的 jar 包引用之后, jackson-core 和 jackson-annotations 這 2 個 jar 包也會自動添加到 maven 項目工程中。
因此我們只需要導入 jackson-databind 的 jar 包即可。我導入的是最新的 jackson-databind 的 jar 包,另外為了方便測試,也導入了最新的 juint 的 jar 包,具體內容如下:
<!--導入 jackson-databind 的 jar 包-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.1</version>
</dependency>
<!--導入 junit 的 jar 包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
配置好引用的 jar 包后,打開右側的 Maven 窗口,刷新一下,這樣 Maven 會自動下載所需的 jar 包文件。
搭建好的項目工程整體目錄比較簡單,具體如下圖所示:

項目工程結構簡單介紹:
com.jobs.bean.employee 員工實體類
test 目錄下的文件介紹:
com.jobs.jsonTest 類是專門用來編寫 junit 單元測試方法,用來測試所編寫的 json 處理方法
resources 下的 data.json 文件中存儲一段 json 數據,用於在本 demo 中進行解析
二、細節展示
com.jobs.bean.employee 員工實體類的內容如下:
package com.jobs.bean;
import java.util.Objects;
public class employee {
private String name; //姓名
private Integer age; //年齡
public employee() {
}
public employee(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
//重寫 equals 和 hashCode 方法,用於 employee 對象的去重:
//當兩個 employee 對象的 name 和 age 屬性值一樣的話,認為是相同的 employee 對象
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
employee employee = (employee) o;
return Objects.equals(name, employee.name) && Objects.equals(age, employee.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
//重新 toString() 方法,用於打印出 employee 對象的細節,方便查看
@Override
public String toString() {
return "employee{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
test 下面 resources 目錄下的 data.json 內容如下:
{
"status": 0,
"msg": "成功",
"data": {
"address": {
"street": "黃金屋",
"city": "科技復興",
"province": "地球"
},
"friends": [
"侯胖胖",
"任肥肥",
"藺贊贊",
"李敦敦",
"楊帥帥"
]
}
}
com.jobs.jsonTest 類是編寫處理 json 數據的測試類,具體內容如下:
package com.jobs;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jobs.bean.employee;
import org.junit.Test;
import java.io.*;
import java.util.*;
public class jsonTest {
//創建對象綁定模型對象 ObjectMapper 對象的實例,方便下面的測試方法直接使用
private ObjectMapper mapper = new ObjectMapper();
//JavaBean 與 Json 之間的轉換
@Test
public void test01() throws Exception {
//將 bean 對象轉換為 json 字符串
employee emp = new employee("侯胖胖", 40);
String json = mapper.writeValueAsString(emp);
System.out.println(json);
//將字符串轉換為 bean 對象
employee result = mapper.readValue(json, employee.class);
System.out.println(result);
}
//Java 自帶的數據結構(里面是 Java 自帶的數據類型)與 Json 之間的轉換
@Test
public void test02() throws Exception {
List<String> list = new ArrayList<>();
list.add("候胖胖");
list.add("任肥肥");
list.add("李敦敦");
//將 List 轉換為 json 字符串
String listJson = mapper.writeValueAsString(list);
System.out.println(listJson);
//將 json 轉換為 List
List<String> listResult = mapper.readValue(listJson, List.class);
System.out.println(listResult);
System.out.println("---------------------------------");
Map<String, Integer> map = new HashMap<>();
map.put("侯胖胖", 40);
map.put("任肥肥", 38);
map.put("李敦敦", 26);
//將 Map 轉換為 json 字符串
String mapJson = mapper.writeValueAsString(map);
System.out.println(mapJson);
//將 json 轉換為 Map
Map<String, Integer> mapResult = mapper.readValue(mapJson, Map.class);
System.out.println(mapResult);
System.out.println("---------------------------------");
Set<String> set = new HashSet<>();
set.add("候胖胖");
set.add("任肥肥");
set.add("李敦敦");
set.add("任肥肥");
set.add("候胖胖");
//將 Set 轉換為 json 字符串
String setJson = mapper.writeValueAsString(set);
System.out.println(setJson);
//將 json 轉換為 Set
Set<String> setResult = mapper.readValue(setJson, Set.class);
System.out.println(setResult);
}
//Java 自帶的數據結構(里面是自定義的 JavaBean 類對象)與 Json 之間的轉換
//需要使用 TypeReference 來將進行 json 與自定義 JavaBean 類對象之間的對應
@Test
public void test03() throws Exception {
List<employee> list = new ArrayList<>();
list.add(new employee("侯胖胖", 40));
list.add(new employee("任肥肥", 38));
list.add(new employee("李敦敦", 26));
//將 List 轉換為 json 字符串
String listJson = mapper.writeValueAsString(list);
System.out.println(listJson);
//將 json 轉換為 List
List<employee> listResult =
mapper.readValue(listJson, new TypeReference<List<employee>>() {});
System.out.println(listResult);
System.out.println("---------------------------------");
Map<String, employee> map = new HashMap<>();
map.put("破壞之王", new employee("侯胖胖", 40));
map.put("埋坑專家", new employee("任肥肥", 38));
map.put("拆蛋大神", new employee("李敦敦", 26));
//將 Map 轉換為 json 字符串
String mapJson = mapper.writeValueAsString(map);
System.out.println(mapJson);
//將 json 轉換為 Map
Map<String, employee> mapResult =
mapper.readValue(mapJson, new TypeReference<Map<String, employee>>() {});
System.out.println(mapResult);
System.out.println("---------------------------------");
Set<employee> set = new HashSet<>();
set.add(new employee("侯胖胖", 40));
set.add(new employee("任肥肥", 38));
set.add(new employee("李敦敦", 26));
set.add(new employee("任肥肥", 38));
set.add(new employee("侯胖胖", 40));
//將 Set 轉換為 json 字符串
String setJson = mapper.writeValueAsString(set);
System.out.println(setJson);
//將 json 轉換為 Set
Set<employee> setResult =
mapper.readValue(setJson, new TypeReference<Set<employee>>() {});
System.out.println(setResult);
}
//不使用 JavaBean ,采用 JsonNode 讀取 Json 字段的數據
@Test
public void test04() throws Exception {
//獲取 data.json 的文件路徑
String dataPath = jsonTest.class
.getClassLoader().getResource("data.json").getPath();
//從 data.json 文件中讀取 json 數據
StringBuilder sb = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(dataPath))) {
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
}
System.out.println("-------------從文件中獲取到的 json 數據:");
String json = sb.toString().replace(" ", "");
System.out.println(json); //把 data.json 文件中的 json 數據打印出來
System.out.println("-------------解析 json 數據:");
//json 具有樹模型的特征,因此可以按照樹形結構進行解析
JsonNode root = mapper.readTree(json);
//獲取 int 類型的 status 值
int status = root.get("status").asInt();
System.out.println("status 為 " + status);
//獲取 String 類型的 msg 值
String msg = root.get("msg").asText();
System.out.println("msg 為 " + msg);
//獲取 address 數據
JsonNode address = root.get("data").get("address");
String street = address.get("street").asText();
String city = address.get("city").asText();
String province = address.get("province").asText();
System.out.println("address 數據如下:");
System.out.println("\t" + "province 為 " + province);
System.out.println("\t" + "city 為 " + city);
System.out.println("\t" + "street 為 " + street);
//獲取 friends 數組數據
JsonNode friends = root.get("data").get("friends");
System.out.println("friends 數據如下:");
for (JsonNode item : friends) {
System.out.println("\t" + item.asText());
}
}
}
需要注意的一點就是:如果想把 json 轉換為自定義的 JavaBean 對象,需要使用 TypeReference 。
上面代碼中最后一個方法,模擬的實際場景是:當我們調用相關接口或從其它某種途徑獲取到 Json 數據時,不想創建與 Json 字段相對應的實體類時,可以采用 Json 樹模型的方案來進行解析,獲取相關 Json 字段的值。
本 demo 的源代碼下載地址為:https://files.cnblogs.com/files/blogs/699532/jacksondemo.zip
