Java中常用JSON解析利器


1. JSON 是什么

JSON(JavaScript Object Notation)是一種輕量級的數據交換格式,易於閱讀和編寫,機器解析和生成起來更是輕而易舉。JSON 采用了完全獨立於編程語言的文本格式,但它的格式非常符合 C 語言家族的習慣(比如 C、C++、C#、Java、JavaScript、Python 等)。 這種特質使得 JSON 成為了最理想的數據交換格式。

JSON 建構於兩種常見的數據結構:

  • “鍵/值”對。
  • 數組。

最常用的JSON解析利器有:Gson、Jackson、阿里巴巴的 Fastjson

2. Gson 

Gson 是谷歌提供的一個開源庫,可以將 Java 對象序列化為 JSON 字符串,同樣可以將 JSON 字符串反序列化(解析)為匹配的 Java 對象。

使用 Gson 之前,需要先在項目中引入 Gson 的依賴。

<!--Gson 依賴-->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.6</version>
</dependency>
        

1)准備數據 Person 類

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
static class Person {
    private Integer age;
    private String username;
}

2)Gson 簡單使用

// Gson 的簡單使用
private static void method1() {
    Gson gson = new Gson();
    gson.toJson(18);            // 18
    gson.toJson("沉默王二");     // 沉默王二
}

// 對象轉 Json
private static void method2() {
    Gson gson = new Gson();
    String json = gson.toJson(new Person(18, "王二"));
    System.out.println(json);
}

// 數組與 Json 之間的相互轉換
private static void method3() {
    Gson gson = new Gson();
    int[] ints = {1, 2, 3, 4, 5};
    String[] strings = {"沉", "默", "王二"};
    // 轉成 JSON 字符串
    gson.toJson(ints);     //  ==> [1,2,3,4,5]
    gson.toJson(strings);  //  ==> ["沉", "默", "王二"]
    //  解析為數組
    int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class);
    String[] strings2 = gson.fromJson("[\"沉\", \"默\", \"王二\"]", String[].class);
}

// 集合轉 Json 字符串,Json 字符串轉集合
private static void method4() {
    // 集合轉Json字符串
    Gson gson = new Gson();
    List<String> list = Lists.newArrayList("沉默", "王二");
    String json = gson.toJson(list);
    System.out.println("集合轉 Json 字符串: " + json);

    // Json 字符串轉集合
    Type collectionType = new TypeToken<List<String>>() {}.getType();
    List<String> list2 = gson.fromJson(json, collectionType);
    System.out.println("Json 字符串轉集合: " + list2);
}

  字符串轉集合時,我們需要借助 com.google.gson.reflect.TypeTokenjava.lang.reflect.Type 來獲取集合的類型,再將其作為參數傳遞給 formJson() 方法,才能將 JSON 字符串解析為集合。

Gson 雖然可以將任意的 Java 對象轉成 JSON 字符串,但將字符串解析為指定的集合類型時就需要花點心思了,因為涉及到了泛型——TypeToken 是解決這個問題的銀彈。

3. Jackson

Jackson 是基於 Stream 構建的一款用來序列化和反序列化 JSON 的 Java 開源庫,社區非常活躍,其版本的更新速度也比較快。

  • 截止到目前,GitHub 上已經星標 5.2K 了;
  • Spring MVC 的默認 JSON 解析器;
  • 與 Gson 相比,Jackson 在解析大的 JSON 文件時速度更快。
  • 與 fastjson 相比,Jackson 更穩定。

在使用 Jackson 之前,需要先添加 Jackson 的依賴。

<!--Jackson 依賴-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>    
    <artifactId>jackson-databind</artifactId>    
    <version>2.9.1</version>
</dependency>  

Jackson 的核心模塊由三部分組成。

  • jackson-core,核心包,提供基於"流模式"解析的相關 API,它包括 JsonPaser 和 JsonGenerator。
  • jackson-annotations,注解包,提供標准注解功能。
  • jackson-databind ,數據綁定包, 提供基於"對象綁定" 解析的相關 API ( ObjectMapper ) 和"樹模型" 解析的相關 API (JsonNode);基於"對象綁定" 解析的 API 和"樹模型"解析的 API 依賴基於"流模式"解析的 API。

當添加 jackson-databind 之后, jackson-core 和 jackson-annotations 也隨之添加到 Java 項目工程中。

1)准備數據 Person 類

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
static class Person{
    private Integer age;
    private String username;
}

2)Jackson 簡單使用

private static void method1() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    // 在反序列化時忽略在 Json 中存在但 JavaBean 中不存在的字段
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // 在序列化時忽略值為null的字段
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    Person person = new Person(18, "王二");

    // 對象轉 Json 字符串
    String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(person);
    System.out.println(json);

    // Json 字符串轉對象
    Person person1 = mapper.readValue(json, Person.class);
    System.out.println(person1.toString());
}

在調用 writeValue() 或者 readValue() 方法之前,往往需要對 JSON 和 JavaBean 之間進行一些定制化配置。

a)在反序列化時忽略在 JSON 中存在但 JavaBean 不存在的字段

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

b)在序列化時忽略值為 null 的字段

mapper.setSerializationInclusion(Include.NON_NULL); 

有些時候,這些定制化的配置對 JSON 和 JavaBean 之間的轉化起着重要的作用。如果需要更多配置信息,查看 DeserializationFeature、SerializationFeature 和 Include 類的 Javadoc 即可。

3. fastjson

fastjson 是阿里巴巴開源的 JSON 解析庫,它可以解析 JSON 格式的字符串,也支持將 Java Bean 序列化為 JSON 字符串。

fastjson 相對於其他 JSON 庫的特點就是快,另外 API 使用起來也非常簡單,更是在 2012 年被開源中國評選為最受歡迎的國產開源軟件之一。

PS:盡管 fastjson 值得信賴,但也鬧過不少腥風血雨,這里就不提了。

在使用 fastjson 之前,需要先添加 fastjson 的依賴。

<!--fastjson 依賴-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>

1)准備數據 Person 類

@Data
@NoArgsConstructor
@ToString
static class Person {
    private Integer age;
    private String username;
    private List<String> books = new ArrayList<>();

    public Person(Integer age, String username) {
        this.age = age;
        this.username = username;
    }

    public void putBook(String bookname) {
        this.books.add(bookname);
    }
}

2)Fastson 簡單使用

private static void method1() {
    // 對象轉 Json 字符串
    Person person = new Person(18,"沉默王二");
    person.putBook("《Web全棧開發進階之路》");
    person.putBook("《深入了解Java虛擬機》");
    String json = JSON.toJSONString(person);
    System.out.println(json);

    // Json 字符串轉對象
    Person person1 = JSON.parseObject(json, Person.class);
    System.out.println(person1);
}

SerializeWriter:相當於StringBuffer

JSONArray:相當於List<Object>

JSONObject:相當於Map<String, Object>

JSON反序列化沒有真正數組,本質類型都是List<Object>

比如說 List<Strudent>     List 轉 Json

List<Student> students = new ArrayList();
String str = JSON.toJSONString(students);     // List 轉 json

Json 轉 List 方法一
String json = ""; //獲取的 Json 數據
List<Student> students = JSON.parseObject(json,new TypeReference<List<Student>>(){}); // Json 轉 List【需要借助 TypeReference 類進行轉化】

Json 轉 List 方法二
List<Student> students = JSON.parseArray(json,Student.class); 

Student 對象要實現 Serializable 接口
import java.io.Serializable;  
public class Student implements Serializable{}

4. 總結

就我個人而言,我是比較推崇 Gson 的,畢竟是谷歌出品的,品質值得信賴,關鍵是用起來也確實比較得勁【API 非常實用,而且復雜數據類型的相互轉換很靠譜】

Jackson 呢,在解析大的 JSON 文件時速度更快,也比 fastjson 穩定;

fastjson 呢,作為我們國產開源軟件中的驕傲,嗯,值得尊敬。

 


免責聲明!

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



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