diff --git a/src/main/java/com/ankurm/jackson3/part5polymorphic/F02DeserialiseMixedList.java b/src/main/java/com/ankurm/jackson3/part5polymorphic/F02DeserialiseMixedList.java new file mode 100644 index 0000000..73efed5 --- /dev/null +++ b/src/main/java/com/ankurm/jackson3/part5polymorphic/F02DeserialiseMixedList.java @@ -0,0 +1,56 @@ +package com.ankurm.jackson3.part5polymorphic; + +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.json.JsonMapper; + +import java.util.List; + +/** + * Post: Polymorphic Deserialisation — https://ankurm.com/jackson-polymorphic-deserialization/ + * Section: "Deserialising a Mixed List" + * + * Deserialisation is the half that works exactly as the post describes — and it is + * also what proves the serialisation defect in F01: feed it the discriminator-less + * JSON and it fails outright. + */ +public class F02DeserialiseMixedList { + + private static final String GOOD_JSON = "[" + + "{\"paymentType\":\"credit_card\",\"paymentId\":1,\"amountDue\":99.99," + + "\"cardNumberLastFour\":\"4242\",\"cardNetwork\":\"VISA\"}," + + "{\"paymentType\":\"bank_transfer\",\"paymentId\":2,\"amountDue\":250.0," + + "\"bankAccountIban\":\"GB29NWBK60161331926819\",\"bankName\":\"National Bank\"}" + + "]"; + + public static void main(String[] args) { + JsonMapper mapper = JsonMapper.builder().build(); + + List payments = + mapper.readValue(GOOD_JSON, new TypeReference>() { }); + + for (PaymentMethod payment : payments) { + if (payment instanceof CreditCardPayment cc) { + System.out.println("Card ending: " + cc.getCardNumberLastFour()); + } else if (payment instanceof BankTransferPayment bt) { + System.out.println("Bank: " + bt.getBankName()); + } + } + + // Now prove the F01 defect matters: the lossy output cannot be read back. + String lossy = mapper.writeValueAsString(F01SerialiseMixedList.samplePayments()); + try { + mapper.readValue(lossy, new TypeReference>() { }); + System.out.println("unreachable"); + } catch (Exception e) { + System.out.println("lossy JSON round-trip -> " + e.getClass().getSimpleName()); + } + + // Whereas the correctly written output does round-trip. + String correct = mapper.writerFor(new TypeReference>() { }) + .writeValueAsString(F01SerialiseMixedList.samplePayments()); + List again = + mapper.readValue(correct, new TypeReference>() { }); + System.out.println("correct JSON round-trip -> " + again.size() + " payments, " + + again.get(0).getClass().getSimpleName() + " first"); + } +}