Part 4: SimpleModule on the builder, and the BigDecimal scale trap
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
package com.ankurm.jackson3.part4custom;
|
||||
|
||||
import tools.jackson.databind.DeserializationFeature;
|
||||
import tools.jackson.databind.json.JsonMapper;
|
||||
import tools.jackson.databind.module.SimpleModule;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Post: Custom Serialisers and Mix-ins — https://ankurm.com/jackson-custom-serializer-mixin/
|
||||
* Section: "Registering the Serialiser and Deserialiser via SimpleModule"
|
||||
*
|
||||
* Jackson 3 differences:
|
||||
* 1. SimpleModule moved to tools.jackson.databind.module.
|
||||
* 2. The Version-taking constructor from the post is gone; pass just a name.
|
||||
* 3. The module is attached with builder.addModule(...), not mapper.registerModule(...),
|
||||
* because a built mapper is immutable.
|
||||
*/
|
||||
public class E03SimpleModuleRegistration {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SimpleModule moneyModule = new SimpleModule("MoneyModule");
|
||||
moneyModule.addSerializer(Money.class, new E01MoneyValueSerializer());
|
||||
moneyModule.addDeserializer(Money.class, new E02MoneyValueDeserializer());
|
||||
|
||||
JsonMapper mapper = JsonMapper.builder()
|
||||
.addModule(moneyModule)
|
||||
.build();
|
||||
|
||||
// Serialise: note the rounding and the upper-casing done by the serialiser.
|
||||
Money price = new Money(new BigDecimal("19.999"), "usd");
|
||||
System.out.println("serialised : " + mapper.writeValueAsString(price));
|
||||
|
||||
// Deserialise. NOTE: the scale is NOT preserved by default — Jackson parses
|
||||
// 20.00 as a double first, so you get 20.0 and not 20.00. The blog post claims
|
||||
// 20.00; that only holds if you turn on USE_BIG_DECIMAL_FOR_FLOATS, below.
|
||||
Money restored = mapper.readValue("{\"amount\":20.00,\"currency\":\"USD\"}", Money.class);
|
||||
System.out.println("amount : " + restored.amount() + " (scale lost)");
|
||||
|
||||
JsonMapper exact = JsonMapper.builder()
|
||||
.addModule(moneyModule)
|
||||
.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
|
||||
.build();
|
||||
System.out.println("amount exact : "
|
||||
+ exact.readValue("{\"amount\":20.00,\"currency\":\"USD\"}", Money.class).amount()
|
||||
+ " (scale preserved)");
|
||||
|
||||
// The path()-based deserialiser tolerates a missing field; the post's get()
|
||||
// version would throw NullPointerException here.
|
||||
Money partial = mapper.readValue("{\"currency\":\"EUR\"}", Money.class);
|
||||
System.out.println("missing field: " + partial);
|
||||
|
||||
// Without the module the record would serialise structurally instead.
|
||||
JsonMapper plain = JsonMapper.builder().build();
|
||||
System.out.println("no module : " + plain.writeValueAsString(price));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user