1. Introduction
1.导言
The Gson library developed by Google is quite a good choice for serialization and deserialization of Java objects to and from JSON format. Besides, we typically come across the problem that Gson shows integers as floating-point numbers while serializing objects.
Google 开发的 Gson 库是将 Java 对象序列化为 JSON 格式或从 JSON 格式反序列化的不错选择。此外,在序列化对象时,我们通常会遇到 Gson 将整数显示为浮点数的问题。
In this tutorial, we’ll see why integers are considered floating-point numbers. Moreover, we’ll provide a solution to prevent Gson from doing that.
在本教程中,我们将了解为什么整数被视为浮点数。此外,我们还将提供一种解决方案,防止 Gson 这样做。
2. Problem Definition
2. 问题定义
Gson serializes Java objects to JSON. By default, Gson serializes integers as floating-point numbers for a more accurate representation. Here’s a simple example:
Gson 可将 Java 对象序列化为 JSON。默认情况下,Gson 会将整数序列化为浮点数,以获得更精确的表示。下面是一个简单的例子:
public String jsonString= "[{\"id\":4077395,\"field_id\":242566,\"body\":\"\"}, " +
"{\"id\":4077398,\"field_id\":242569,\"body\":[[273019,0],[273020,1],[273021,0]]}, " +
"{\"id\":4077399,\"field_id\":242570,\"body\":[[273022,0],[273023,1],[273024,0]]}]";
Here, we declared a JSON string called jsonString that represents an array of objects. This JSON array has different fields, such as id, field_id, and body.
在这里,我们声明了一个名为 jsonString 的 JSON 字符串,它代表一个对象数组。这个 JSON 数组有不同的字段,例如 id、field_id、 和body。
Now, we’ll use the Gson library for JSON string deserialization into a list of Hashtable<String, Object> objects.
现在,我们将使用 Gson 库将 JSON 字符串反序列化为 Hashtable<String, Object> 对象的 list 列表。
ArrayList<Hashtable<String, Object>> responses;<br/>
Type ResponseList = new TypeToken<ArrayList<Hashtable<String, Object>>>() {}.getType();<br/>
responses = new Gson().fromJson(jsonString, ResponseList);
ArrayList<Hashtable<String, Object>> Response;<br/>
Type ResponseList = new TypeToken<ArrayList<Hashtable<String, Object>>>() {}.getType();<br/>
responses = new Gson().fromJson(jsonString, ResponseList);</代码
Here, we declare an ArrayList named responses to contain elements of type Hashtable with String keys and Object values. Moreover, we utilize the Gson library for deserializing the jsonString into a list of Hashtables.
在这里,我们声明了一个名为 responses 的 ArrayList 来包含 Hashtable 类型的元素,其中包含 String 键和 Object 值。此外,我们还利用 Gson 库将 jsonString 反序列化为 Hashtables 列表。
Finally, we use the TypeToken to get generic type information during deserialization.
最后,我们在反序列化过程中使用 TypeToken 获取通用类型信息。
The responses will be formatted as follows:
回复的格式如下:
[{
body = ,
field_id = 242566.0,
id = 4077395.0
}, {
body = [
[273019.0, 0.0],
[273020.0, 1.0],
[273021.0, 0.0]
],
field_id = 242569.0,
id = 4077398.0
}, {
body = [
[273022.0, 0.0],
[273023.0, 1.0],
[273024.0, 0.0]
],
field_id = 242570.0,
id = 4077399.0
}]
Note that the Gson represents integers as floating-point numbers.
请注意,Gson 将整数表示为浮点数。
3. Default Number Strategy in Gson
3.Gson 中的默认数字策略
Gson’s default number strategy aims to strike a balance between accuracy and flexibility when representing numeric values. The decision to use floating-point numbers for integers is based on the idea that JSON lacks explicit support for distinguishing between integer and floating-point types. Therefore, Gson opts for a default strategy that ensures the preservation of precision in numeric values.
在表示数值时,Gson 的默认数字策略旨在兼顾准确性和灵活性。之所以决定使用浮点数代替整数,是因为 JSON 缺乏区分整数和浮点类型的明确支持。因此,Gson 选择了一种默认策略,以确保数值的精确性。
However, this default behavior may not align with specific requirements or preferences, especially when dealing with scenarios where integers should remain integers in the JSON representation.
但是,这种默认行为可能不符合特定要求或偏好,尤其是在处理 JSON 表示法中整数应保持整数的情况时。
4. Using setObjectToNumberStrategy() Method
4.使用 setObjectToNumberStrategy() 方法
Using the Gson method setObjectToNumberStrategy(), we can thoroughly control the functionalities of the object-to-number conversion mechanism during the deserialization process.
通过使用 Gson 方法 setObjectToNumberStrategy() ,我们可以在反序列化过程中彻底控制对象到数字转换机制的功能。
Let’s explore this capability through an illustrative example:
让我们通过一个示例来探讨这种功能:
public static String expectedOutput ="[{body=, field_id=242566, id=4077395}, " +
"{body=[[273019, 0], [273020, 1], [273021, 0]], field_id=242569, id=4077398}, " +
"{body=[[273022, 0], [273023, 1], [273024, 0]], field_id=242570, id=4077399}]";
@Test
public void givenJsonString_whenUsingsetObjectToNumberStrategyMethod_thenValidateOutput() {
Gson gson = new GsonBuilder()
.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
.create();
ArrayList<Hashtable<String, Object>> responses = gson.fromJson(jsonString,
new TypeToken<ArrayList<Hashtable<String, Object>>>() {}.getType());
assertEquals(expectedOutput, responses.toString());
}
Here, the use of the setObjectToNumberStrategy() method enables us to set up a strategy such as ToNumberPolicy.LONG_OR_DOUBLE for Gson to direct its behavior in regard to numeric values. Finally, we verify the conversion process using the assertEquals() method.
在这里,使用 setObjectToNumberStrategy() 方法,我们可以为 Gson 设置一个策略,例如 ToNumberPolicy.LONG_OR_DOUBLE 以指导其处理数值的行为。最后,我们使用 assertEquals() 方法验证转换过程。
Moreover, the ToNumberPolicy enum in Gson supports various strategies for handling numeric values. Besides ToNumberPolicy.LONG_OR_DOUBLE, which we used in the example, other strategies include:
此外,Gson 中的 ToNumberPolicy 枚举支持各种处理数值的策略。除了我们在示例中使用的 ToNumberPolicy.LONG_OR_DOUBLE 之外,其他策略包括:
- ToNumberPolicy.DOUBLE_ONLY: converts all numeric values to double during deserialization
- ToNumberPolicy.LONG_ONLY: converts all numeric values to long during deserialization
- ToNumberPolicy.DEFAULT: retains Gson’s default behavior, representing integers as floating-point numbers
5. Conclusion
5.结论
In this article, we discuss an issue encountered with Gson: integers are automatically converted to floating-point numbers during the serialization process. To resolve this problem, we use the setObjectToNumberStrategy() method.
本文将讨论 Gson 遇到的一个问题:在序列化过程中,整数会自动转换为浮点数。为了解决这个问题,我们使用了 setObjectToNumberStrategy() 方法。
As always, the complete code samples for this article can be found over on GitHub.
与往常一样,本文的完整代码示例可在 GitHub 上找到。