Java 大数反序列化引发NumberFormatException
我编写了下面的程序来将Java 大数反序列化引发NumberFormatException,java,json,java-8,jackson,jackson-databind,Java,Json,Java 8,Jackson,Jackson Databind,我编写了下面的程序来将参数转换为JsonNode。设置3.9E38时获取NumberFormatException。如何在JsonNode中设置BigDecimal public class JsonCheck { public static void main(String[] args) throws JsonProcessingException { ObjectMapper om = new ObjectMapper(); Parameter p
参数
转换为JsonNode
。设置3.9E38
时获取NumberFormatException
。如何在JsonNode中设置BigDecimal
public class JsonCheck {
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper om = new ObjectMapper();
Parameter p = new Parameter();
p.setPrevValue(new BigDecimal("3.9E38"));
JsonNode node = om.convertValue(p,JsonNode.class);
System.out.println(node);
}
public static class DefaultValueSerializer extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeNumber(o.toPlainString());
}
}
public static class Parameter {
@JsonSerialize(using = DefaultValueSerializer.class)
private BigDecimal prevValue;
public void setPrevValue(BigDecimal prevValue) {
this.prevValue = prevValue;
}
public BigDecimal getPrevValue() {
return prevValue;
}
}
}
public类JsonCheck{
公共静态void main(字符串[]args)引发JsonProcessingException{
ObjectMapper om=新的ObjectMapper();
参数p=新参数();
p、 setPrevValue(新的BigDecimal(“3.9E38”);
JsonNode=om.convertValue(p,JsonNode.class);
System.out.println(节点);
}
公共静态类DefaultValueSerializer扩展JsonSerializer{
@凌驾
public void serialize(BigDecimal o、JsonGenerator、JsonGenerator、SerializerProvider SerializerProvider)引发IOException{
writeNumber(o.toPlainString());
}
}
公共静态类参数{
@JsonSerialize(使用=DefaultValueSerializer.class)
私有值;
公共void setPrevValue(BigDecimal prevValue){
this.prevValue=prevValue;
}
公共BigDecimal getPrevValue(){
返回值;
}
}
}
看起来是这样的,因为反序列化(在您的转换中)过程中使用的com.fasterxml.jackson.core.JsonParser
实现无法解析真正大的数字。默认情况下,数字被视为Long
,值3.9E38
超出其范围。不幸的是,在这种情况下没有处理特性和属性,我们需要在这里编写定制。请参见以下示例:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.util.JsonParserDelegate;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import java.math.BigDecimal;
public class JsonApp {
public static void main(String[] args) {
Parameter parameter = new Parameter();
parameter.setPrevValue(new BigDecimal("3.9E38"));
SimpleModule module = new SimpleModule();
module.addDeserializer(JsonNode.class, new BigDecimalFirstJsonNodeDeserializer());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
JsonNode node = mapper.convertValue(parameter, JsonNode.class);
System.out.println(node);
}
}
class BigDecimalFirstJsonNodeDeserializer extends JsonNodeDeserializer {
@Override
public JsonNode deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return super.deserialize(new BigDecimalJsonParser(p), ctxt);
}
}
class BigDecimalJsonParser extends JsonParserDelegate {
public BigDecimalJsonParser(JsonParser parser) {
super(parser);
}
@Override
public NumberType getNumberType() {
return NumberType.BIG_DECIMAL;
}
@Override
public BigDecimal getDecimalValue() throws IOException {
String value = getText();
return new BigDecimal(value);
}
}
class BigDecimalPlainStringJsonSerializer extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeNumber(o.toPlainString());
}
}
class Parameter {
@JsonSerialize(using = BigDecimalPlainStringJsonSerializer.class)
private BigDecimal prevValue;
public void setPrevValue(BigDecimal prevValue) {
this.prevValue = prevValue;
}
public BigDecimal getPrevValue() {
return prevValue;
}
}
@michalk,更新了代码示例。需要以
非科学
格式转换数字。因此,使用o.toPlainString()
您不需要为BigDecimal
定制Jackson序列化程序。
{"prevValue":3.9E+38}