Erste Schritte mit der benutzerdefinierten Deserialisierung in Jackson

1. Übersicht

Dieses kurze Tutorial zeigt, wie Sie mit Jackson 2 JSON mithilfe eines benutzerdefinierten Deserializers deserialisieren .

Wenn Sie tiefer graben und andere coole Dinge lernen möchten, die Sie mit dem Jackson 2 tun können, besuchen Sie das Haupt-Tutorial von Jackson.

2. Standarddeserialisierung

Beginnen wir mit der Definition von zwei Entitäten und sehen, wie Jackson eine JSON-Darstellung für diese Entitäten ohne Anpassung deserialisiert:

public class User { public int id; public String name; } public class Item { public int id; public String itemName; public User owner; }

Definieren wir nun die JSON-Darstellung, die wir deserialisieren möchten:

{ "id": 1, "itemName": "theItem", "owner": { "id": 2, "name": "theUser" } }

Lassen Sie uns diesen JSON schließlich für Java-Entitäten freigeben:

Item itemWithOwner = new ObjectMapper().readValue(json, Item.class);

3. Individuelle Deserializer auf ObjectMapper

Im vorherigen Beispiel stimmte die JSON-Darstellung perfekt mit den Java-Entitäten überein. Als Nächstes vereinfachen wir JSON:

{ "id": 1, "itemName": "theItem", "createdBy": 2 }

Wenn Sie die Bereitstellung für genau dieselben Entitäten aufheben - dies schlägt standardmäßig fehl:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "createdBy" (class org.baeldung.jackson.dtos.Item), not marked as ignorable (3 known properties: "id", "owner", "itemName"]) at [Source: [email protected]; line: 1, column: 43] (through reference chain: org.baeldung.jackson.dtos.Item["createdBy"])

Wir werden dieses Problem lösen, indem wir unsere eigene Deserialisierung mit einem benutzerdefinierten Deserializer durchführen :

public class ItemDeserializer extends StdDeserializer { public ItemDeserializer() { this(null); } public ItemDeserializer(Class vc) { super(vc); } @Override public Item deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonNode node = jp.getCodec().readTree(jp); int id = (Integer) ((IntNode) node.get("id")).numberValue(); String itemName = node.get("itemName").asText(); int userId = (Integer) ((IntNode) node.get("createdBy")).numberValue(); return new Item(id, itemName, new User(userId, null)); } }

Wie Sie sehen können, arbeitet der Deserializer mit der Standard-Jackson-Darstellung von JSON - dem JsonNode . Sobald der Eingabe-JSON als JsonNode dargestellt ist , können wir nun die relevanten Informationen daraus extrahieren und unsere eigene Item- Entität erstellen .

Einfach ausgedrückt, müssen wir diesen benutzerdefinierten Deserializer registrieren und den JSON einfach normal deserialisieren:

ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(Item.class, new ItemDeserializer()); mapper.registerModule(module); Item readValue = mapper.readValue(json, Item.class);

4. Benutzerdefinierter Deserializer für die Klasse

Alternativ können wir den Deserializer auch direkt in der Klasse registrieren :

@JsonDeserialize(using = ItemDeserializer.class) public class Item { ... }

Da der Deserializer auf Klassenebene definiert ist, muss er nicht im ObjectMapper registriert werden. Ein Standard-Mapper funktioniert einwandfrei:

Item itemWithOwner = new ObjectMapper().readValue(json, Item.class);

Diese Art der Konfiguration pro Klasse ist sehr nützlich in Situationen, in denen wir möglicherweise keinen direkten Zugriff auf den zu konfigurierenden unformatierten ObjectMapper haben.

5. Schlussfolgerung

Dieser Artikel zeigt, wie Sie Jackson 2 nutzen können, um nicht standardmäßige JSON-Eingaben zu lesen - und wie Sie diese Eingaben einem beliebigen Java-Entity-Diagramm mit vollständiger Kontrolle über die Zuordnung zuordnen.

Die Implementierung all dieser Beispiele und Codefragmente finden Sie auf GitHub - es ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.