Die Jackson-Bibliothek ist ein leistungsstarkes Werkzeug zur Verarbeitung von JSON-Daten in Java. Eine besonders nützliche Funktion sind die Annotationen @JsonSerialize und @JsonDeserialize, mit denen Entwickler benutzerdefinierte Serialisierer und Deserialisierer für die Konvertierung von Java-Objekten in JSON und umgekehrt erstellen können. In diesem Artikel werden wir diese Annotationen anhand eines praxisnahen Beispiels demonstrieren: der benutzerdefinierten Verarbeitung von Geldbeträgen.

Money-Objekt mit Währung und Betrag

Angenommen, wir haben ein Java-Objekt namens Money, das einen Geldbetrag mit einer zugehörigen Währung repräsentiert. Hier ist die Definition des Objekts:

import java.math.BigDecimal;
import java.util.Currency;

public class Money {

    private Currency currency;
    private BigDecimal amount;

    // Konstruktor, Getter und Setter
}Code-Sprache: PHP (php)

Unser Ziel ist es, die Konvertierung dieses Money-Objekts nach JSON und zurück zu steuern, indem wir benutzerdefinierte Serialisierer und Deserialisierer implementieren.

Benutzerdefinierter Serialisierer für Money

Um einen benutzerdefinierten Serialisierer für das Money-Objekt zu erstellen, implementieren wir die JsonSerializer<T>-Schnittstelle. In diesem Beispiel konzentrieren wir uns darauf, den Geldbetrag als String mit zwei Dezimalstellen zu serialisieren:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;

public class MoneySerializer extends JsonSerializer<Money> {

    @Override
    public void serialize(Money money, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException {
        // Benutzerdefinierte Serialisierungslogik: Geldbetrag als String mit zwei Dezimalstellen
        String formattedAmount = String.format("%.2f %s", money.getAmount(), money.getCurrency().getCurrencyCode());
        jsonGenerator.writeString(formattedAmount);
    }
}Code-Sprache: JavaScript (javascript)

Hier wird der Geldbetrag als String mit zwei Dezimalstellen und der zugehörigen Währung als Währungscode serialisiert.

Benutzerdefinierter Deserialisierer für Money

Um einen benutzerdefinierten Deserialisierer zu erstellen, implementieren wir die JsonDeserializer<T>-Schnittstelle. Im Falle des Money-Objekts erwarten wir, dass der JSON-String in einen Geldbetrag und eine Währung aufgeteilt wird:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;

public class MoneyDeserializer extends JsonDeserializer<Money> {

    @Override
    public Money deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException {
        // Benutzerdefinierte Deserialisierungslogik: JSON-String in Geldbetrag und Währung aufteilen
        String[] parts = jsonParser.getText().split(" ");
        BigDecimal amount = new BigDecimal(parts[0]);
        Currency currency = Currency.getInstance(parts[1]);

        return new Money(currency, amount);
    }
}Code-Sprache: JavaScript (javascript)

Hier wird der JSON-String aufgeteilt, um den Geldbetrag und die Währung zu extrahieren und ein neues Money-Objekt zu erstellen.

Money-Objekt mit Annotationen verwenden

Nun können wir die erstellten Serialisierer und Deserialisierer in unserem Money-Objekt verwenden:

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

@JsonSerialize(using = MoneySerializer.class)
@JsonDeserialize(using = MoneyDeserializer.class)
public class Money {

    private Currency currency;
    private BigDecimal amount;

    // Konstruktor, Getter und Setter
}Code-Sprache: JavaScript (javascript)

Durch das Hinzufügen der @JsonSerialize– und @JsonDeserialize-Annotationen weisen wir Jackson an, unsere benutzerdefinierten Serialisierer und Deserialisierer zu verwenden.

Praktisches Beispiel

Hier ist, wie Sie das Money-Objekt in Ihrer Anwendung verwenden können:

import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {

    public static void main(String[] args) throws Exception {
        // Erstellen eines Money-Objekts
        Money money = new Money(Currency.getInstance("USD"), new BigDecimal("123.45"));

        // Jackson-ObjectMapper zum Konvertieren zwischen Java-Objekt und JSON verwenden
        ObjectMapper objectMapper = new ObjectMapper();

        // Java-Objekt in JSON konvertieren (Serialisierung)
        String jsonString = objectMapper.writeValueAsString(money);
        System.out.println("Serialized JSON: " + jsonString);

        // JSON in Java-Objekt konvertieren (Deserialisierung)
        Money deserializedMoney = objectMapper.readValue(jsonString, Money.class);
        System.out.println("Deserialized Money: " + deserializedMoney.getAmount() + " " + deserializedMoney.getCurrency().getCurrencyCode());
    }
}Code-Sprache: JavaScript (javascript)

In diesem Beispiel demonstriert das Money-Objekt mit benutzerdefinierten Serialisierern und Deserialisierern, wie die Standardkonvertierung von Java-Objekten in JSON und umgekehrt angepasst werden kann.

Fazit

Die @JsonSerialize– und @JsonDeserialize-Annotationen von Jackson ermöglichen es Entwicklern, die JSON-Konvertierung von Java-Objekten nach ihren Bedürfnissen anzupassen. Durch die Implementierung benutzerdefinierter Serialisierer und Deserialisierer kann die Verarbeitung komplexer Objekte, wie im Beispiel des Money-Objekts gezeigt, präzise gesteuert werden. Dies bietet eine flexible und mächtige Lösung für die Integration von JSON-Daten in Java-Anwendungen.