1
0

Part 5: all four @JsonTypeInfo include strategies, executed

This commit is contained in:
2026-08-04 17:32:58 +00:00
parent fc5844966a
commit 439bc33e7d

View File

@@ -0,0 +1,54 @@
package com.ankurm.jackson3.part5polymorphic;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import tools.jackson.databind.json.JsonMapper;
/**
* Post: Polymorphic Deserialisation — https://ankurm.com/jackson-polymorphic-deserialization/
* Section: "@JsonTypeInfo Placement Options"
*
* The post gives a table of the four include strategies. This runs all four so you
* can see the actual wire format instead of trusting the table.
*/
public class F03IncludeStrategies {
// ---- As.PROPERTY: discriminator is an ordinary field inside the object ----
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "kind")
@JsonSubTypes(@JsonSubTypes.Type(value = PropCard.class, name = "card"))
public interface PropBase { }
public record PropCard(double amountDue) implements PropBase { }
// ---- As.WRAPPER_OBJECT: object wrapped in a single-key envelope ----
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes(@JsonSubTypes.Type(value = WrapObjCard.class, name = "card"))
public interface WrapObjBase { }
public record WrapObjCard(double amountDue) implements WrapObjBase { }
// ---- As.WRAPPER_ARRAY: two-element [name, object] array ----
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_ARRAY)
@JsonSubTypes(@JsonSubTypes.Type(value = WrapArrCard.class, name = "card"))
public interface WrapArrBase { }
public record WrapArrCard(double amountDue) implements WrapArrBase { }
// ---- As.EXISTING_PROPERTY: reuses a field the class already declares ----
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "kind", visible = true)
@JsonSubTypes(@JsonSubTypes.Type(value = ExistingCard.class, name = "card"))
public interface ExistingBase { String kind(); }
public record ExistingCard(String kind, double amountDue) implements ExistingBase { }
public static void main(String[] args) {
JsonMapper mapper = JsonMapper.builder().build();
System.out.println("PROPERTY : " + mapper.writeValueAsString((PropBase) new PropCard(99.0)));
System.out.println("WRAPPER_OBJECT : " + mapper.writeValueAsString((WrapObjBase) new WrapObjCard(99.0)));
System.out.println("WRAPPER_ARRAY : " + mapper.writeValueAsString((WrapArrBase) new WrapArrCard(99.0)));
System.out.println("EXISTING_PROPERTY : " + mapper.writeValueAsString((ExistingBase) new ExistingCard("card", 99.0)));
// Each form reads back to the correct concrete type.
System.out.println("read PROPERTY -> " + mapper.readValue("{\"kind\":\"card\",\"amountDue\":99.0}", PropBase.class));
System.out.println("read WRAPPER_OBJECT -> " + mapper.readValue("{\"card\":{\"amountDue\":99.0}}", WrapObjBase.class));
System.out.println("read WRAPPER_ARRAY -> " + mapper.readValue("[\"card\",{\"amountDue\":99.0}]", WrapArrBase.class));
}
}