1
0

Part 0: shared immutable mapper, with the Jackson 2 lines that no longer apply

This commit is contained in:
2026-08-04 17:29:09 +00:00
parent 52503ad26e
commit 4af1f1ee14

View File

@@ -0,0 +1,64 @@
package com.ankurm.jackson3.part0setup;
import com.fasterxml.jackson.annotation.JsonInclude;
import tools.jackson.databind.DeserializationFeature;
import tools.jackson.databind.json.JsonMapper;
import java.time.LocalDate;
/**
* Post: Jackson 101 — https://ankurm.com/jackson-java-tutorial/
* Section: "The ObjectMapper Lifecycle — The One Rule That Matters Most"
*
* Build the mapper ONCE at startup and share it. In Jackson 3 this is enforced
* by the API rather than by convention: the built mapper has no setters at all.
*/
public class A02SharedMapperConfiguration {
public record Invoice(Long invoiceId, String customerName, LocalDate issuedOn, String note) { }
/**
* The Jackson 3 equivalent of the classic Spring @Bean ObjectMapper.
*
* Three of the four settings people habitually copy from Jackson 2 tutorials
* are unnecessary or wrong in Jackson 3 — the comments say which and why.
*/
static JsonMapper buildSharedMapper() {
return JsonMapper.builder()
// NOT NEEDED: FAIL_ON_UNKNOWN_PROPERTIES already defaults to false in
// Jackson 3. Listed here only because it is the single most-copied line
// from Jackson 2 configuration; deleting it changes nothing.
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
// NOT NEEDED: java.time support is built into jackson-databind 3.x and
// dates already serialise as ISO-8601 strings. There is no
// SerializationFeature.WRITE_DATES_AS_TIMESTAMPS in Jackson 3 — the flag
// moved to tools.jackson.databind.cfg.DateTimeFeature and is off by
// default. See beyond/Y03DateTimeDefaults for proof.
// Skip null fields. Jackson 2's setSerializationInclusion(...) and the
// builder's serializationInclusion(...) do NOT exist in Jackson 3.
// The real API is changeDefaultPropertyInclusion.
.changeDefaultPropertyInclusion(
incl -> incl.withValueInclusion(JsonInclude.Include.NON_NULL))
.build();
}
public static void main(String[] args) {
JsonMapper mapper = buildSharedMapper();
Invoice invoice = new Invoice(500L, "Alice", LocalDate.of(2026, 4, 9), null);
System.out.println("configured : " + mapper.writeValueAsString(invoice));
JsonMapper plain = JsonMapper.builder().build();
System.out.println("defaults : " + plain.writeValueAsString(invoice));
// Proof that the mapper is immutable: ObjectMapper in Jackson 3 exposes no
// set*() mutators at all, so there is no way to reconfigure a shared instance.
long setterCount = java.util.Arrays.stream(
tools.jackson.databind.ObjectMapper.class.getMethods())
.filter(m -> m.getName().startsWith("set"))
.count();
System.out.println("ObjectMapper set*() methods in Jackson 3: " + setterCount);
}
}