Gson Builder — 特殊類型 Floats & Doubles

原文鏈接:Gson Builder — Special Values of Floats & Doubles
原文出自:Norman Peitek
譯者:無名無

上一節介紹了 lenient 的使用方法,通過設置 lenient 屬性,Gson 可以幫我忽略一些錯誤,保證解析儘量的匹配 Java 對象。本文將瞭解下 Gson 是如何解析特殊類型 Floats 和 Doubles。

特殊類型 Floats & Doubles

這兩種類型是 Java 中常見的類型,用來表示一些特定類型的值,但是在 JSON 中並沒有這些類型。

讓我們引用 Gson 中關於這個問題的解釋:

JSON 規範的第2.4節不允許特殊的double值(NaN,Infinity,-Infinity),但是,Javascript規範(見第4.3.20,4.3.22,4.3.23節)允許這些值作爲有效的 Javascript 值。 此外,大多數 JavaScript 引擎將接受 JSON 中的這些特殊值,而沒有問題。 因此,在實際應用中,即使不能作爲 JSON 規範,但是接受這些值作爲有效的 JSON 是有意義的。

我們在 lenient 的使用中知道,序列化是遵循 JSON 標準的,反序列化的問題可以通過設置 lenient 屬性來忽略,如果你 Java 對象中包含一個正常的 Floats 或者 Doubles 類型的數據,是可以正常序列化得到 JSON的,如果你傳入 Float.POSITIVE_INFINITY 值,Gson 將會拋出異常,因爲這個值是不能符合 JSON 標準的。

解決的辦法就是通過 GsonBuilder 設置 serializeSpecialFloatingPointValues() 方法

例如:

public class UserFloat {  
    String name;
    Float weight;

    public UserFloat(String name, Float weight) {
        this.name = name;
        this.weight = weight;
    }
}

UserFloat user = new UserFloat("Norman", Float.POSITIVE_INFINITY);  

Gson gson = new Gson();

UserFloat user = new UserFloat("Norman", Float.POSITIVE_INFINITY);

String usersJson = gson.toJson(user); // will throw an exception  

java.lang.IllegalArgumentException: Infinity is not a valid double value as per JSON specification. To override this behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method.

    at com.google.gson.Gson.checkValidFloatingPoint(Gson.java:324)
    at com.google.gson.Gson$3.write(Gson.java:316)
    at com.google.gson.Gson$3.write(Gson.java:302)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:125)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:243)
    at com.google.gson.Gson.toJson(Gson.java:669)
    at com.google.gson.Gson.toJson(Gson.java:648)
    at com.google.gson.Gson.toJson(Gson.java:603)

解決:

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.serializeSpecialFloatingPointValues();
    Gson gson = gsonBuilder.create();
    UserFloat userFloat = new UserFloat("Norman", Float.POSITIVE_INFINITY);
    String usersJson = gson.toJson(userFloat);
    System.out.println("userJson:" + usersJson); 

注意:有了這個方法,並不意味着你可以隨意的配置 JSON 數據格式,建議還是要遵循標準的 JSON 規範。

目標

瞭解 Gson 序列化不規範的數據結構 Float 和 Double類型,Gson 默認是不支持的,需要單獨設置。

練習代碼已上傳 Github https://github.com/whiskeyfei/Gson-Review 可自行查看。

Gson 系列文章翻譯回顧

1、Gson - Java-JSON 序列化和反序列化入門
2、Gson - 映射嵌套對象
3、Gson - Arrays 和 Lists 映射對象
4、Gson - Map 結構映射
5、Gson - Set 集合映射
6、Gson - 空值映射
7、Gson Model Annotations - 如何使用 @SerializedName 更改字段的命名
8、Gson Model Annotations - @SerializedName 匹配多個反序列化名稱
9、Gson Builder - 基礎和命名規則
10、Gson Builder - 序列化空值
11、Gson Builder - 忽略策略
12、Gson Builder - Gson Lenient 屬性
13、Gson Builder - 特殊類型 Floats & Doubles
17、Gson Builder - 如何使用 @Expose 忽略字段
19、Gson Advanced - 映射枚舉類型
20、Gson Advanced - 映射循環引用
21、Gson Advanced - 泛型
22、Gson Advanced - 簡單自定義序列化 (Part 1)
24、Gson Advanced - 自定義反序列化基礎
25、Gson Advanced - 自定義對象實例創建
26、Gson Advanced - 通過 @JsonAdapter 自定義(反)序列化過程
32、Practical Gson - 如何解析多態對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章