Java 使用 Jackson 處理 Json 數據


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 包文件。

搭建好的項目工程整體目錄比較簡單,具體如下圖所示:

image

項目工程結構簡單介紹:

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




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM