Java to Jackson JSON serialization: Money fields

jackson, java, serialization

Solution

You can use a custom serializer at your money field. Here's an example with a MoneyBean. The field amount gets annotated with @JsonSerialize(using=...).

public class MoneyBean {
    //...

    @JsonProperty("amountOfMoney")
    @JsonSerialize(using = MoneySerializer.class)
    private BigDecimal amount;

    //getters/setters...
}

public class MoneySerializer extends JsonSerializer<BigDecimal> {
    @Override
    public void serialize(BigDecimal value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
            JsonProcessingException {
        // put your desired money style here
        jgen.writeString(value.setScale(2, BigDecimal.ROUND_HALF_UP).toString());
    }
}

That's it. A BigDecimal is now printed in the right way. I used a simple testcase to show it:

@Test
public void jsonSerializationTest() throws Exception {
     MoneyBean m = new MoneyBean();
     m.setAmount(new BigDecimal("20.3"));

     ObjectMapper mapper = new ObjectMapper();
     assertEquals("{\"amountOfMoney\":\"20.30\"}", mapper.writeValueAsString(m));
}

Problem

Currently, I'm using Jackson to send out JSON results from my Spring-based web application. The problem I'm having is trying to get all money fields to output with 2 decimal places. I wasn't able to solve this problem using `setScale(2)`, as numbers like 25.50 are truncated to 25.5 etc Has anyone else dealt with this problem? I was thinking about making a Money class with a custom Jackson serializer... can you make a custom serializer for a field variable? You probably can... But even still, how could I get my customer serializer to add the number as a number with 2 decimal places?

Original source