java - 防止Gson在反序列化数字时将整数转换为小数

标签 java json groovy gson

我编写了以下 Spock 测试来演示反序列化包含数字的 JSON 对象时出现的问题

class GsonFactorySpec extends Specification {

    private Gson gson = GsonFactory.instance.gsonInstance

    private String JSON = '{"number": 2}'

    def 'deserialize a JSON document with an integer value to a Map'() {

        when:
        Map deserialized = gson.fromJson(JSON, Map)

        then:
        deserialized.number instanceof Integer
    }
}

测试失败,因为数字被反序列化为 Double值为 2.0 而不是 Integer 2.

在我创建 Gson 的工厂类中例如,我尝试为 Number 的实例注册适配器

@Singleton
class GsonFactory {

    private final JsonSerializer<Number> numberSerializer = new JsonSerializer<Number>() {
        @Override
        JsonElement serialize(Number number, Type type, JsonSerializationContext context) {
            Integer intValue = number.toInteger()
            intValue == number ? new JsonPrimitive(intValue) : new JsonPrimitive(number)
        }
    }

    Gson getGsonInstance() {
        new GsonBuilder().serializeNulls().registerTypeHierarchyAdapter(
            Number, numberSerializer).create()
    }
} 

但似乎在反序列化期间没有调用此适配器。是否可以强制将整数反序列化为整数?

更新

A new feature added在 Gson 2.8.5 版本中看起来可能有助于解决这个问题

最佳答案

您缺少正确的类型信息:Map.class不提供类型参数化,因此Gson使用String键和Object值(尽管Object(反)序列化不能被覆盖,所以这就是对象层次结构策略不起作用的原因)。在 Java 中,它会是这样的:

private static final Type mapStringToNumberType = new TypeToken<Map<String, Number>>() {}.getType();

public static void main(final String... args) {
    @SuppressWarnings("unchecked")
    final Map<String, Number> map = gson.fromJson("{\"number\": 2}", mapStringToNumberType);
    System.out.println(map.get("number"));
}

您可能也对这个陈旧的 PR 感兴趣解决了类似的问题。

关于java - 防止Gson在反序列化数字时将整数转换为小数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55286855/

相关文章:

java - Spring Data Mongodb 转换 Joda LocalDateTime

java - Windows 更新后 DecimalFormat 无法正常工作

javascript - 使用ajax调用获取包含3个数组的json对象并将数组传递给javascript

java - java中如何实现 map 列表的字符串转换

groovy - 漏洞? Groovy 中的 "Reference to method is ambiguous"

java - 我可以在 android 上用 java 一次读取来读取整个文件吗?

java - 在java中,如何使用正则表达式模式来解析 "Event=Bell,time=9000,rings=5"以获​​取事件名称和两个数字字符串?

java - java中带有类型属性的JSON到XML

grails - Grails按位运算符

database - 使用 Grails 访问没有域类的数据库