java 在 Gson 双序列化中关闭科学记数法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11119094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
switch off scientific notation in Gson double serialization
提问by konstantin
When I use Gson to serialize an Object that contains a double value close to zero it is using the scientific E-notation:
当我使用 Gson 序列化一个包含接近于零的双精度值的对象时,它使用的是科学 E 符号:
{"doublevaule":5.6E-4}
How do I tell Gson to generate
我如何告诉 Gson 生成
{"doublevaule":0.00056}
instead? I can implement a custom JsonSerializer, but it returns a JsonElement. I would have to return a JsonPrimitive containing a double having no control about how that is serialized.
反而?我可以实现自定义 JsonSerializer,但它返回一个 JsonElement。我将不得不返回一个 JsonPrimitive,其中包含一个无法控制如何序列化的双精度值。
Thanks!
谢谢!
回答by Brian Agnew
Why not provide a new serialiser for Double
? (You will likely have to rewrite your object to use Double
instead of double
).
为什么不为 提供一个新的序列化程序Double
?(您可能必须重写您的对象以使用Double
而不是double
)。
Then in the serialiser you can convert to a BigDecimal
, and play with the scale etc.
然后在序列化器中,您可以转换为 a BigDecimal
,并使用比例等。
e.g.
例如
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Double.class, new JsonSerializer<Double>() {
@Override
public JsonElement serialize(final Double src, final Type typeOfSrc, final JsonSerializationContext context) {
BigDecimal value = BigDecimal.valueOf(src);
return new JsonPrimitive(value);
}
});
gson = gsonBuilder.create();
The above will render (say) 9.166666E-6
as 0.000009166666
以上将呈现(说)9.166666E-6
为0.000009166666
回答by Ron Klein
A minor change on Brian Agnew's answer:
布赖恩·阿格纽 (Brian Agnew) 的回答略有变化:
public class DoubleJsonSerializer implements JsonSerializer<Double> {
@Override
public JsonElement serialize(final Double src, final Type typeOfSrc, final JsonSerializationContext context) {
BigDecimal value = BigDecimal.valueOf(src);
try {
value = new BigDecimal(value.toBigIntegerExact());
} catch (ArithmeticException e) {
// ignore
}
return new JsonPrimitive(value);
}
}
回答by swanson
Create a custom serializer for Double
为以下对象创建自定义序列化程序 Double
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Double.class, new JsonSerializer<Double>() {
@Override
public JsonElement serialize(Double originalValue, Type typeOf, JsonSerializationContext context) {
BigDecimal bigValue = BigDecimal.valueOf(originalValue);
return new JsonPrimitive(bigValue.toPlainString());
}
});
Before: {"Amount": 1.0E9}
之前:{“金额”:1.0E9}
After: {"Amount": "1000000000"}
之后:{“金额”:“1000000000”}
Not exactly perfect since it's a String in the JSON.
不完全完美,因为它是 JSON 中的字符串。
回答by unteleportedman
Internally GSON uses Number#toString so we just need to create a new instance of a Number:
GSON 在内部使用 Number#toString,所以我们只需要创建一个 Number 的新实例:
.registerTypeAdapter(Double.class, new JsonSerializer<Double>() {
@Override
public JsonElement serialize(final Double src, final Type typeOfSrc, final JsonSerializationContext context) {
Number n = new Number() {
@Override
public long longValue() {
return 0;
}
@Override
public int intValue() {
return 0;
}
@Override
public float floatValue() {
return 0;
}
@Override
public double doubleValue() {
return 0;
}
@Override
public String toString() {
return new BigDecimal(src).toPlainString();
}
};
return new JsonPrimitive(n);
}
})
回答by Joachim Sauer
You could try extending JsonWriter
and overriding the method value(double)
您可以尝试扩展JsonWriter
和覆盖该方法value(double)
It doesn't seem to be built to be modified like this (you'll pretty much need to duplicate the existing code), but it should be possible to get it working.
它似乎不是为了像这样修改而构建的(您几乎需要复制现有代码),但应该可以让它工作。
Unfortunately I see no other reason to influence the output format.
不幸的是,我认为没有其他原因可以影响输出格式。
回答by Elnatan Derech
With Kotlin:
使用科特林:
val gsonBuilder = GsonBuilder()
gsonBuilder.registerTypeAdapter(object: TypeToken<Double>() {}.type, object : JsonSerializer<Double> {
override fun serialize(src: Double, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
val value = BigDecimal.valueOf(src)
return JsonPrimitive(value)
}
})
val gson = gsonBuilder.create()