GSON异常 - 打印字段名称,在序列化Nan时会出错

时间:2013-09-20 16:11:02

标签: java gson nan

我正在使用Gson,遇到了序列化对象的问题:

java.lang.IllegalArgumentException: NaN 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:296)
    ...

有没有办法让Gson打印出有问题的类名/字段名?我可以按照建议使用serializeSpecialFloatingPointValues()方法,但理想情况下我想了解我的对象有NaN的位置。

--------更新----------------

经过艰苦的踩踏,我认为原因是一个未经双重化的双重原因。我的设置如下:

public class Foo {
    private double price;
}

String jsonFromNet = ...;
Foo foo = Gson.fromJson(jsonFromNet);
Gson.toJson(foo, Foo.class); <-- throws the exception

来自我的api的返回json不包括属性“price”,所以我猜成员变量“d”未被初始化。当我去序列化时,gson会抛出错误。

如果我在序列化之前给“price”一个显式值,或者恰好在api json响应中,那么一切正常。

此外,如果我将“价格”从双倍更改为浮动,那么它似乎并不介意未初始化的状态。

我现在将研究GsonBuilder.serializeSpecialFloatingPointValues(),我只是想知道double在这种状态下是如何序列化的。我可以使用默认值零或其他东西。

由于

2 个答案:

答案 0 :(得分:1)

解决这一难解问题的最简单方法是替换默认值

Gson()

通过

GsonBuilder().serializeSpecialFloatingPointValues().create()

这里以Android单元测试类为例(科特琳)

import com.google.gson.GsonBuilder
import org.junit.Assert
import org.junit.Test

class NanGSONParsingTest {
    data class FloatContainer(val includedFloat: Float)

    @Test
    fun gsonCanHandleNanParsing() {
        val container = FloatContainer(Float.NaN)
        val gson = GsonBuilder().serializeSpecialFloatingPointValues().create()
        val jsonString = gson.toJson(container)//{"includedFloat":NaN}
        val parsedBackContainer = gson.fromJson<FloatContainer>(jsonString, FloatContainer::class.java)
        Assert.assertEquals(container,parsedBackContainer)
    }
}

答案 1 :(得分:0)

严格来说,答案是否定的。我检查了源代码,据我所知,我无法看到一个点,您可以使用Gson自定义行为获取所需内容。

但是在考虑这个答案时,我想到了4个想法,无论如何都要获得你需要的信息。最终的目标是不惜一切代价发现这个领域,不是吗?。

  1. 下载Gson代码,在checkValidFloatingPoint方法中抛出异常之前设置断点,并在boundField.name e中检查com.google.gson.internal.bind.Adapter<T>.writ的值。这是令人讨厌的领域。
  2. 下载Gson代码并自定义上一点的方法,以便在捕获到IllegalArgumentException时打印出有问题的字段。 (提出补丁;))
  3. 使用serializeSpecialFloatingPointValues(),序列化为JSON字符串,然后使用正则表达式搜索,找到字符串中的每个Nan。附近有您要查找的字段名称或数组字段名称。
  4. 构建您自己的类扫描程序,通过反射检查每个双字段来检查value是否为null。当然,在这种情况下,不需要Gson。无论如何,这将是一个有趣的练习。