I'm having a problem in which jackson is deserializing numeric values into arbitrary types which I cannot predict. For example, if someone passes the value "14", jackson will instantiate it as an Integer
. However, if someone passes the value "14.01" then jackson will instantiate it as a Double
. This is a problem because I have a custom deserializer (@JsonCreator
) which is throwing exceptions since I cannot predictable cast the field into a BigDecimal. Ideally jackson would just turn everything into a BigDecimal
.
I found a post which suggests that Jackson might be capable of doing something like this. Deserialize JSON into a generic map, forcing all JSON floats into Decimal or String, in Jackson
However, I can't figure out how to access the mapper object hidden inside Spring Boot in order to run the appropriate method mapper.enable()
.
Here is a snippet of the deserializer:
@JsonCreator
public OptionTransaction(Map<String,Object> jsonObj){
Map<String,Object> jsonOption = (Map<String, Object>) jsonObj.get("option");
Map<String,Object> optionPriceObj = (Map<String, Object>) jsonOption.get("price");
BigDecimal optionValue = new BigDecimal((Double) optionPriceObj.get("value"));
As you can see above, that Double
cast is a problem because jackson is sometimes not feeding in doubles. Does anyone know an easy way to get jackson to either always output BigDecimals, or even just strings?
UPDATE:
As far as getting doubles converted to BigDecimal, I accomplished this by modifying application.properties in the following way:
# ===============================
# = DESERIALIZATION CUSTOMIZATION
# ===============================
spring.jackson.deserialization.USE_BIG_DECIMAL_FOR_FLOATS=true
@JsonCreator
public OptionTransaction(Map<String,Object> jsonObj){
Map<String,Object> jsonOption = (Map<String, Object>) jsonObj.get("option");
Map<String,Object> optionPriceObj = (Map<String, Object>) jsonOption.get("price");
BigDecimal optionValue = new BigDecimal((Double) optionPriceObj.get("value"));
}
..
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
OptionTransaction transaction = mapper.readValue(jsonString, OptionTransaction.class);
https://github.com/FasterXML/jackson-databind/wiki/Deserialization-Features
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With