There are many posts about creating Jackson serializers for numbers, currency, etc. For engineering applications, there is often a need to set the precision on numbers based on the units or other criteria.
For example, spatial coordinates might be constrained to 5 or 6 digits after the decimal point, and temperature might be constrained to 2 digits after the decimal point. Default serializer behavior that has too many digits or truncated exponential notation is not good. What I need is something like:
@JsonSerialize(using=MyDoubleSerializer.class, precision=6) double myValue;
and better yet be able to specify the precision at run-time. I am also using a MixIn. I could write a serializer for each class but hoped to specify on specific values.
Any ideas would be appreciated.
The Jackson Object mapper can parse JSON into objects of classes developed by you, or into objects of the built-in JSON tree model explained later in this tutorial. By the way, the reason it is called ObjectMapper is because it maps JSON into Java Objects (deserialization), or Java Objects into JSON (serialization).
Note that Jackson does not use java. io. Serializable for anything: there is no real value for adding that. It gets ignored.
You may use Jackson's ContextualSerializer
to achieve desired serialization as shown below.
Firstly, create an annotation to capture precision
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Precision {
int precision();
}
Next, create a contextual serializer for Double
type which looks for Precision
annotation on the field to be serialized and then create a new serializer for the specified precision.
public class DoubleContextualSerializer extends JsonSerializer<Double> implements ContextualSerializer {
private int precision = 0;
public DoubleContextualSerializer (int precision) {
this.precision = precision;
}
public DoubleContextualSerializer () {
}
@Override
public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
if (precision == 0) {
gen.writeNumber(value.doubleValue());
} else {
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(precision, RoundingMode.HALF_UP);
gen.writeNumber(bd.doubleValue());
}
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
Precision precision = property.getAnnotation(Precision.class);
if (precision != null) {
return new DoubleContextualSerializer (precision.precision());
}
return this;
}
}
Finally, annotate your field to use custom serializer and set precision
public class Bean{
@JsonSerialize(using = DoubleContextualSerializer .class)
@Precision(precision = 2)
private double doubleNumber;
}
Hope this helps!!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With