Erste Schritte mit der benutzerdefinierten Deserialisierung in Jackson

Erste Schritte mit der benutzerdefinierten Deserialisierung in Jackson

1. Überblick

Dieses kurze Tutorial zeigt, wie Sie mit Jackson 2 JSON mitcustom Deserializer deserialisieren.

Wenn Sie tiefer graben undother cool things you can do with the Jackson 2 lernen möchten, gehen Sie zuthe main Jackson tutorial.

2. Standard-Deserialisierung

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. Benutzerdefinierter Deserializer aufObjectMapper

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

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

Wenn Sie die Zuordnung zu genau denselben Entitäten aufheben, schlägt dies natürlich standardmäßig fehl:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "createdBy" (class org.example.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.example.jackson.dtos.Item["createdBy"])

Wir lösen dies, indem wirour own deserialization with a custom Deserializer ausfü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 - denJsonNode. Sobald der Eingabe-JSON alsJsonNode dargestellt ist, können wir jetztextract the relevant information from it und unsere eigeneItem-Entität erstellen.

Einfach ausgedrückt, müssen wirregister this custom deserializer und den JSON normal 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 auchregister the deserializer directly on the class:

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

Da der Deserializer auf Klassenebene definiert ist, muss er nicht aufObjectMapper 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 die zu konfigurierenden rohenObjectMapperhaben.

5. Fazit

Dieser Artikel zeigt, wie Sie Jackson 2 aufread non-standard JSON input setzen - und wie Sie diese Eingabe einem beliebigen Java-Entity-Diagramm mit vollständiger Kontrolle über die Zuordnung zuordnen.

Die Implementierung all dieser Beispiele und Codefragmentecan be found in my github project - dies ist ein Eclipse-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.