Part 2: Optional is native in Jackson 3; NON_ABSENT vs null
This commit is contained in:
@@ -0,0 +1,51 @@
|
|||||||
|
package com.ankurm.jackson3.part2modernjava;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import tools.jackson.databind.json.JsonMapper;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post: Jackson with Records, Optionals, Sealed Classes
|
||||||
|
* https://ankurm.com/jackson-java-records-optionals/
|
||||||
|
* Section: "Jackson with Optional<T>"
|
||||||
|
*
|
||||||
|
* Jackson 3 handles Optional natively. There is no jackson-datatype-jdk8
|
||||||
|
* dependency in the pom and no registerModule(new Jdk8Module()) call — those are
|
||||||
|
* Jackson 2 requirements, and the Jdk8Module class does not exist under
|
||||||
|
* tools.jackson at all.
|
||||||
|
*/
|
||||||
|
public class C02OptionalFields {
|
||||||
|
|
||||||
|
public record CustomerProfile(String customerName, Optional<String> middleName) { }
|
||||||
|
|
||||||
|
/** NON_ABSENT is the inclusion value that understands Optional.empty(). */
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_ABSENT)
|
||||||
|
public record CompactProfile(String customerName, Optional<String> middleName) { }
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
JsonMapper mapper = JsonMapper.builder().build();
|
||||||
|
|
||||||
|
// Present value: the Optional is unwrapped, not wrapped in {"present":true}.
|
||||||
|
System.out.println("present : "
|
||||||
|
+ mapper.writeValueAsString(new CustomerProfile("Alice", Optional.of("Marie"))));
|
||||||
|
|
||||||
|
// Empty Optional: serialises as null by default.
|
||||||
|
System.out.println("empty : "
|
||||||
|
+ mapper.writeValueAsString(new CustomerProfile("Bob", Optional.empty())));
|
||||||
|
|
||||||
|
// NON_ABSENT omits the property entirely instead of writing null.
|
||||||
|
System.out.println("absent : "
|
||||||
|
+ mapper.writeValueAsString(new CompactProfile("Bob", Optional.empty())));
|
||||||
|
|
||||||
|
// Deserialise back.
|
||||||
|
String json = "{\"customerName\":\"Alice\",\"middleName\":\"Marie\"}";
|
||||||
|
CustomerProfile restored = mapper.readValue(json, CustomerProfile.class);
|
||||||
|
System.out.println("isPresent: " + restored.middleName().isPresent());
|
||||||
|
|
||||||
|
// A missing property deserialises to Optional.empty(), never to null.
|
||||||
|
CustomerProfile missing = mapper.readValue("{\"customerName\":\"Carol\"}", CustomerProfile.class);
|
||||||
|
System.out.println("missing -> " + missing.middleName() + " (null? "
|
||||||
|
+ (missing.middleName() == null) + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user