我在下面编写了将Parameter
转换为JsonNode
的程序。设置NumberFormatException
时得到3.9E38
。如何在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;
}
}
}
答案 0 :(得分:1)
之所以这样,是因为在反序列化(在您的情况下为转换)过程中使用的addWeighted
实现无法解析很大的数字。默认情况下,数字被视为com.fasterxml.jackson.core.JsonParser
,而值Long
超出了它的范围。不幸的是,在这种情况下无法处理功能USE_BIG_DECIMAL_FOR_FLOATS和USE_BIG_INTEGER_FOR_INTS,因此我们需要在此处编写自定义项。参见以下示例:
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;
}
}