我正在使用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在这种状态下是如何序列化的。我可以使用默认值零或其他东西。
由于
答案 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个想法,无论如何都要获得你需要的信息。最终的目标是不惜一切代价发现这个领域,不是吗?。
checkValidFloatingPoint
方法中抛出异常之前设置断点,并在boundField.name
e中检查com.google.gson.internal.bind.Adapter<T>.writ
的值。这是令人讨厌的领域。serializeSpecialFloatingPointValues()
,序列化为JSON字符串,然后使用正则表达式搜索,找到字符串中的每个Nan。附近有您要查找的字段名称或数组字段名称。