[java] Java to Jackson JSON serialization: Money fields

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?

This question is related to java serialization jackson

The answer is


As Sahil Chhabra suggested you can use @JsonFormat with proper shape on your variable. In case you would like to apply it on every BigDecimal field you have in your Dto's you can override default format for given class.

@Configuration
public class JacksonObjectMapperConfiguration {

    @Autowired
    public void customize(ObjectMapper objectMapper) {
         objectMapper
            .configOverride(BigDecimal.class).setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.STRING));
    }
}

I had the same issue and i had it formatted into JSON as a String instead. Might be a bit of a hack but it's easy to implement.

private BigDecimal myValue = new BigDecimal("25.50");
...
public String getMyValue() {
    return myValue.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
}

Instead of setting the @JsonSerialize on each member or getter you can configure a module that use a custome serializer for a certain type:

SimpleModule module = new SimpleModule();
module.addSerializer(BigInteger.class, new ToStringSerializer());
objectMapper.registerModule(module);

In the above example, I used the to string serializer to serialize BigIntegers (since javascript can not handle such numeric values).


I'm one of the maintainers of jackson-datatype-money, so take this answer with a grain of salt since I'm certainly biased. The module should cover your needs and it's pretty light-weight (no additional runtime dependencies). In addition it's mentioned in the Jackson docs, Spring docs and there were even some discussions already about how to integrate it into the official ecosystem of Jackson.


Inspired by Steve, and as the updates for Java 11. Here's how we did the BigDecimal reformatting to avoid scientific notation.

public class PriceSerializer extends JsonSerializer<BigDecimal> {
    @Override
    public void serialize(BigDecimal value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
        // Using writNumber and removing toString make sure the output is number but not String.
        jgen.writeNumber(value.setScale(2, RoundingMode.HALF_UP));
    }
}

You can use @JsonFormat annotation with shape as STRING on your BigDecimal variables. Refer below:

 import com.fasterxml.jackson.annotation.JsonFormat;

  class YourObjectClass {

      @JsonFormat(shape=JsonFormat.Shape.STRING)
      private BigDecimal yourVariable;

 }

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to serialization

laravel Unable to prepare route ... for serialization. Uses Closure TypeError: Object of type 'bytes' is not JSON serializable Best way to save a trained model in PyTorch? Convert Dictionary to JSON in Swift Java: JSON -> Protobuf & back conversion Understanding passport serialize deserialize How to generate serial version UID in Intellij Parcelable encountered IOException writing serializable object getactivity() Task not serializable: java.io.NotSerializableException when calling function outside closure only on classes not objects Cannot deserialize the JSON array (e.g. [1,2,3]) into type ' ' because type requires JSON object (e.g. {"name":"value"}) to deserialize correctly

Examples related to jackson

No Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator JSON parse error: Can not construct instance of java.time.LocalDate: no String-argument constructor/factory method to deserialize from String value How to convert JSON string into List of Java object? Deserialize Java 8 LocalDateTime with JacksonMapper java.lang.IllegalArgumentException: No converter found for return value of type java.lang.ClassNotFoundException: com.fasterxml.jackson.annotation.JsonInclude$Value How to modify JsonNode in Java? Deserialize JSON with Jackson into Polymorphic Types - A Complete Example is giving me a compile error Convert Map to JSON using Jackson Required request body content is missing: org.springframework.web.method.HandlerMethod$HandlerMethodParameter