Home > Software engineering >  Serialize BigDecimal attribute from a webservice to have a scale of 2
Serialize BigDecimal attribute from a webservice to have a scale of 2

Time:08-09

The consumer of the SpringBoot webservice needs to receive a response JSON representing an object with multiple properties, one which represents tax with a BigDecimal type. The current implementation returns a value of

{
...
tax: 2.2
...
}

but the consumer wants the value to be represented like this:

{
...
tax: 2.20
...
}

Is there a way to do this serialization of the value, without making it a String in the JSON response?

BEFORE EDIT

I have tried creating a custom Deserializer like so:

public class BigDecimal2JsonDeserializer extends NumberDeserializers.BigDecimalDeserializer {

    @Override
    public BigDecimal deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        BigDecimal value = super.deserialize(p, ctxt);
        value = value.setScale(2, BigDecimal.ROUND_HALF_EVEN);
        return value;
    }
}

and then implement it like so:

public class ResponseObjectDto {
@JsonDeserialize(using = BigDecimal2JsonDeserializer.class)
private BigDecimal tax;
}

but it was unsuccessfull.

AFTER EDIT

I have also tried using a serializer but i haven't found a way to output a numeric value in the JSON, with the correct scale of 2.20

Note: yes, i'm aware that 2.2 = 2.20 and that it will be read correctly by the deserializer, it's just what the consumer asked me to implement

CodePudding user response:

It is possible if you create a custom serializer extending the StdSerializer class and include in its serialize method the BigDecimal#setScale-int-java.math.RoundingMode method:

public class CustomSerializer extends StdSerializer<BigDecimal> {

    public CustomSerializer() {
        super(BigDecimal.class);
    }

    @Override
    public void serialize(BigDecimal t, JsonGenerator jg, SerializerProvider sp) throws IOException {
        BigDecimal value = t.setScale(2, RoundingMode.HALF_EVEN);
        jg.writeNumber(value);
    }
}

Then you can annotate the BigDecimal field with the JsonSerialize annotation obtaining the expected result:

public class ResponseObjectDto {

    @JsonSerialize(using = CustomSerializer.class)
    private BigDecimal tax;
}
  • Related