Hi !
In Jackson, there is a settings to output a BigDecimal as a plain string instead of the scientific annotation : SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN. With this settings enabled, the serializer will call BigDecimal.toPlainString() instead of BigDecimal.toString().
To achieve this in my Play (Java) application :
1) I use a custom GlobalSettings class in which I configure the play Json API :
@Override
public void onStart(Application app) {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN);
Json.setObjectMapper(mapper);
}
2) I created a simple route that map /test to my controller method which is :
public static Result test() {
return ok(Json.toJson(BigDecimal.valueOf(100)));
}
However, when testing this route, the output is :
1E+2
I expected the output :
100
So it looks like the object mapper settings are not taken into account when serializing a JsonNode from a play controller...
Looking at the play source code, I found that a JsonNode is serialised via JsonNode.toString() method in the method JavaResults.writeJson() :
def writeJson(implicit codec: Codec): Writeable[com.fasterxml.jackson.databind.JsonNode] = Writeable(json => codec.encode(json.toString), Some(ContentTypes.JSON))
JsonNode.toString() delegates this operation to DecimalNode.asText() which in turn calls BigDecimal.toString(), which uses the scientific notation... My custom object mapper settings can't be use in this case !
Would it be possible to use ObjectMapper.writeValueAsString(Object) on a JsonNode instead of the JsonNode.toString() method ?
For example :
def writeJson(implicit codec: Codec): Writeable[com.fasterxml.jackson.databind.JsonNode] = Writeable(json => codec.encode(mapper.writeValueAsString(json)), Some(ContentTypes.JSON))
What do you think of this solution ? Is there a workaround in the mean time ?