Reputation: 2117
I am using jackson with spring to serialize/deserialize from Java to JSON and vice-versa.
When jackson serializes my Java object to JSON, the double values with zero decimal value is stripped off while the ones which have decimal values are taken into account. For eg: 550.77 is serialized correctly to 550.77 while 440.00 is serialized to 440 (to an integer equivalent).
How can i ensure my serialization of double with .00 as decimal value is retained?
@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.ANY, setterVisibility = Visibility.NONE)
public class Price extends DTO {
private static final long serialVersionUID = -3986616090347452845L;
private Double _exclVat;
private Double _inclVat;
public Price(){
super();
}
public Price(Double pExclVat, Double pInclVat) {
this();
_exclVat = pExclVat;
_inclVat = pInclVat;
}
public Double getExclVat() {
return _exclVat;
}
public void setExclVat(Double pExclVat) {
_exclVat = pExclVat;
}
public Double getInclVat() {
return _inclVat;
}
public void setInclVat(Double pInclVat) {
_inclVat = pInclVat;
}
}
JSON FORMAT
"price" : {
"excl_vat" : 250.0,
"incl_vat" : 208.33
}
Would it be possible to have 250.00 returned while JSON serialization instead of 250.0?
Upvotes: 1
Views: 9971
Reputation: 75964
The reason why this is behaving like this is clearly noted in the Double toString method java doc. So in your case it doesn't really matter how many zeroes you have in the fractinal part. Here is the excerpt
How many digits must be printed for the fractional part of m or a? There must be at least one digit to represent the fractional part, and beyond that as many, but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type double. That is, suppose that x is the exact mathematical value represented by the decimal representation produced by this method for a finite nonzero argument d. Then d must be the double value nearest to x; or if two double values are equally close to x, then d must be one of them and the least significant bit of the significand of d must be 0.
As the other answer already noted you can use custom serailizer and use decimal formatter to format the values like you prefer.
Or you should consider using BigDecimal for monetory variables with needed precison and scale.
Upvotes: 2
Reputation: 13255
If you really need exactly two decimal places, you may try writing your own number serializer, like
public class DecimalJsonSerializer extends JsonSerializer<Double> {
@Override
public void serialize(Double value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeString( String.format("%.2f", value));
}
}
Then use it annotating each field with it
@DecimalJsonSerializer(using=PriceJsonSerializer.class)
private Double _exclVat;
@DecimalJsonSerializer(using=PriceJsonSerializer.class)
private Double _inclVat;
No custom deserializer should be needed. Default deserializer should be able to handle numbers formatted in such way just fine.
Upvotes: 5