Gson使用方法詳解


一、概述

  Gson是google提供的用來操作json數據的一個非常好用的類庫。其使用范圍非常的廣泛,所以非常有必要對其進行系統的學習。

  json是一種數據格式,確切的說是一種文本數據格式。其在網絡通訊過程中的作用非常的明顯。
  目前大多數的網絡通訊格式已經從xml替換為json格式。
  其提供了序列化和反序列化的功能。在我們進行網絡開發的過程中通常會把參數封裝成json格式傳給后台,后台解析后的返回結果也會封裝成json格式返回給調用者。
  下面就針對json的用法做一下詳細的描述。ps:重要。在查看第三方庫的源代碼或者自己封裝庫的時候尤其重要。對json不熟悉是無法封裝成基於json的高質量庫的。
  例如:Retrofit的網絡數據轉換的converter。GsonConverterFactory.create()

二、從小例子入手

  ps:Book.java

  下面用到的所有實體都是基於Book.java類的。代碼如下:

package com.yw.gsonlib;

import com.google.gson.annotations.SerializedName;

/**
 * create by yangwei
 * on 2020-02-21 18:08
 */
public class Book {
    public Book(){}
    private String id;
    /**
     * 加上@SerializedName注解后服務端api返回name、bookName、Name、bn時,客戶端都能夠拿到正確的值給name屬性。
     */
    @SerializedName(value = "bookName",alternate = {"Name","bn"})
    private String name;

    public Book(String id, String name) {
        this.id = id;
        this.name = name;

    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

  

  1.如何創建一個Gson對象

   /**
     * 創建Gson對象的兩種形式
     */
    private void createGsonObject() {
        //第一種方式
        Gson gson = new Gson();
        //第二種方式
        Gson gson1 = new GsonBuilder().create();
        //方式二除了可以創建一個Gson對象以外還可以進行多項配置,例如,設置日期的格式化
//       例如: new GsonBuilder().setDateFormat("yyyy-MM-dd");
    }

  

  2.如何創建一個JsonObject

 /**
     * 如何創建一個json對象
     */
    private void createJsonObject() {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("id", "1");//給jsonObject創建一個id屬性值為1
        jsonObject.addProperty("bookName", "《深入Java虛擬機》");
        jsonObject.addProperty("bookPrice", 36.8);
        jsonObject.addProperty("bookColor", "紅色");
        //打印Json字符串
        System.out.println(jsonObject.toString());
        //給JsonObject添加對象
        JsonObject jsonObject1 = new JsonObject();
        jsonObject1.addProperty("chapterId", "1");
        jsonObject1.addProperty("chapterName", "第一章");
        //給JsonObject添加實體對象
        jsonObject.add("chapter", jsonObject1);
        System.out.println(jsonObject.toString());


    }

  

  3.數組的序列化與反序列化

/**
     * 根據一個json創建一個數組
     */
    private void createJsonArray() {
        //把數組轉換為Json字符串
        String[] args = new String[]{"《深入Java虛擬機》", "《Android插件編程》", "《OpenCV全解》"};
        Gson gson = new Gson();
        String jsonStr = gson.toJson(args);//先創建一個Json字符串
        System.out.println(jsonStr);//輸出
        //把Json字符串轉換為Json數組
        String[] strArray = gson.fromJson(jsonStr, String[].class);
        for (String s : strArray) {
            System.out.println(s);
        }
    }

  

  4.List的序列化與反序列化

 /**
     * 根據一個json創建一個list
     */
    private void createJsonToList() {
        //將list集合轉換為json字符串
        List<Book> books = new ArrayList<>();
        books.add(new Book("1", "《深入Java虛擬機》"));
        books.add(new Book("2", "《OpenCV進階》"));
        books.add(new Book("3", "《深入Android源代碼》"));
        Gson gson = new Gson();
        String jsonListStr = gson.toJson(books);
        System.out.println(jsonListStr);
        //將json字符串轉換為list集合
        //獲取泛型的類型
        Type type = new TypeToken<List<Book>>() {
        }.getType();
        //使用gson將字符串轉換為泛型集合,即List<Book>
        List<Book> books1 = gson.fromJson(jsonListStr, type);
        for (Book book : books1) {
            System.out.println(book.getName());
        }
    }

  

  5.序列化與反序列化綜合例子(基於Book對象)

 /**
     * json的序列化與反序列化
     * 使用toJson實現序列化,使用fromJson實現反序列化
     */
    private void jsonSeriaReSeria() {
        Gson gson = new Gson();
        Book book = new Book("1", "《深入Java虛擬機》");
        //將book類序列化成字符串
        String bookStr = gson.toJson(book);
        System.out.println(bookStr);
        //將bookStr反序列化成為Book類
        Book b = gson.fromJson(bookStr, Book.class);
        System.out.println(b.getName());
    }

  

  6.如何為屬性做兼容性處理(重命名、預設名稱等)

 /**
     * 如何給json屬性重命名
     * 假設我們有這樣一個需求:由於接口改版,從服務端返回的api中的book字段的name屬性,變為了bookName。如果我們
     * 仍然用name進行解析,則接不到bookName的值,而由於服務端沒有返回name,則解析后name=null。如果要考慮到兼容性那么我們的的Book類的屬性就
     * 需要做一下兼容性的處理。
     * 使用@SerializedName可以給屬性重命名。用@SerializedName的alternate屬性給Book的屬性做擴展
     */
    private void reNameProperty() {
        String bookJson = "{\"id\":\"1\",\"bookName\":\"《深入Java虛擬機》\"}";
        Gson gson = new Gson();
        Book book = gson.fromJson(bookJson, Book.class);
        System.out.println(book.getName());
    }

  

  7.GsonBuilder的一些基礎配置

/**
     * 對GsonBuilder一些屬性介紹
     */
    private void gsonBuilderProperty() {
        Gson gson = new GsonBuilder()
                .serializeNulls()//默認情況下如果某一個屬性為null,那么此屬性不會參與序列化和反序列化的過程,加上此屬性后會參與序列化和反序列化的過程
                .setPrettyPrinting()//格式化json字符串的輸出,默認情況下是輸出一行,經過這個屬性設置后會格式化輸出,即有縮進的輸出
                .setDateFormat("yyyy-MM-dd HH:mm:ss")//對時間進行格式化
                .create();
    }

  

  8.TypeAdapter使用方法介紹

 /**
     * typeAdapter的使用方法
     * TypeAdapter是一個泛型抽象類,用於接管某種類型的序列化和反序列化的過程
     * 它包含兩個抽象方法write和read,分別用於自定義的序列化和反序列化的過程
     */
    private void useTypeAdapter() {
        Gson gson = new GsonBuilder().registerTypeAdapter(Book.class,new BookTypeAdapter()).create();
        Book book = new Book("1","深入Java虛擬機");
        System.out.println(gson.toJson(book));

        String bookJson = "{\"Id\":\"1\",\"Name\":\"《深入Java虛擬機》\"}";
        Book book1 = gson.fromJson(bookJson,Book.class);
        System.out.println(gson.toJson(book1));
    }

  以下是BookTypeAdapter的代碼介紹

package com.yw.gsonlib;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;

/**
 * create by yangwei
 * on 2020-02-23 15:12
 */
public class BookTypeAdapter extends TypeAdapter<Book> {
    /**
     * 序列化接口
     *
     * @param jsonWriter
     * @param book
     * @throws IOException
     */
    @Override
    public void write(JsonWriter jsonWriter, Book book) throws IOException {
        //流式序列化對象開始
        jsonWriter.beginObject();
        //將Json的key值都指定為首字母大寫
        jsonWriter.name("Id").value(book.getId());
        jsonWriter.name("Name").value(book.getName());
        //流式序列化對象結束
        jsonWriter.endObject();
    }

    /**
     * 反序列化接口
     *
     * @param jsonReader
     * @return
     * @throws IOException
     */
    @Override
    public Book read(JsonReader jsonReader) throws IOException {
        Book book = new Book();
        //流式反序列化開始
        jsonReader.beginObject();
        while (jsonReader.hasNext()) {
            switch (jsonReader.nextName()) {
                case "id":
                case "Id":
                    book.setId(jsonReader.nextString());
                    break;
                case "name":
                case "Name":
                    book.setName(jsonReader.nextString());
                    break;
            }
        }
        //流式反序列化結束
        jsonReader.endObject();
        return book;
    }
}

  

三、總結

 講到這里gson的內容基本上就講完了,相信小伙伴們對gson已經有了一個全面的了解。主要要清楚:如何序列化與反序列化,如何自定義序列化過程、如何更改屬性,如何創建對象、如何對泛型進行序列化與反序列化。

ps:由於后面會講到Retrofit2的數據轉換工廠的實現方式(GsonConverterFactory.create()),對於基礎比較薄弱的開發者來說補充一下Gson相關知識,再接着看Retrofit2的轉換工廠的實現原理會非常的清晰。

  另外下一節將介紹自定義泛型,gons和自定義泛型了解清楚后再去看源代碼的實現流程,你會發現根本不需要動腦子,一看就明白了。

  

 


免責聲明!

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



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