Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 大数反序列化引发NumberFormatException_Java_Json_Java 8_Jackson_Jackson Databind - Fatal编程技术网

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}