Force spring boot jackson deserializer to use BigDecimal

11,216
@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

Share:
11,216
melchoir55
Author by

melchoir55

Natural Language Processing, C#, Java, Drools, OpenRemote/Home Automation, Object Oriented Design/Development, Python

Updated on June 12, 2022

Comments

  • melchoir55
    melchoir55 almost 2 years

    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