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