100 % lokal — Ihre Daten verlassen nie Ihren Browser

JSON in Java — Records, die Jackson decodiert

Ein JSON-Beispiel in Java-Records verwandeln. Boxed-Typen und Jackson-Annotation, wo ein Name abweichen musste — das Payload decodiert wie geschrieben.

Sofort Privat Null Cookies

JSON-Eingabe

Java-Ausgabe

Was dieses Werkzeug tut

Aus einer JSON-Probe werden Java-Records, einer je Objekt.

{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
public record Root(
    Long id,
    String firstName,
    Address address
) {}

public record Address(
    String city
) {}

Records sind der kürzeste Weg, in modernem Java „Daten und sonst nichts“ auszudrücken: Konstruktor, Zugriffsmethoden, equals, hashCode und toString kommen mit. Nötig ist Java 16 oder neuer.

Der Schlüssel übersteht die Umbenennung

Ein Komponentenname folgt Javas Regeln: kein Bindestrich, keine führende Ziffer, kein Schlüsselwort. content-type wird contentType, class wird class_, 2fa wird f2fa. Jedes Mal, wenn der Name sich ändern muss, reist der ursprüngliche Schlüssel mit:

import com.fasterxml.jackson.annotation.JsonProperty;

public record Root(
    @JsonProperty("content-type") String contentType,
    @JsonProperty("class") Long class_,
    Boolean ok
) {}

Ohne diese Annotation sucht Jackson nach contentType und findet nichts — der Record liest das Dokument, aus dem er erzeugt wurde, nicht mehr. Sie fehlte bis zum Schreiben dieser Seite; der Fehler ist behoben, und die Annotation erscheint nur dort, wo der Name sich wirklich geändert hat, mit ihrem Import.

Gepackte Typen, und warum

Jede Zahl ist ein Long oder ein Double, jeder Wahrheitswert ein Boolean. JSON kennt null, Javas primitive Typen nicht, und ein double, das ein null empfängt, wird 0.0 — ein Wert, den man von einer echten Null nicht mehr unterscheidet. Die gepackten Typen halten null darstellbar, so wie das Format es erlaubt.

Aus demselben Grund werden null und unbekannte Werte Object, und ein Array davon eine List<Object>.

Was eine Probe nicht sagen kann

Nichts ist optional und nichts trägt @Nullable: jede Komponente ist da, weil das Dokument sie hatte. Records sind oberflächlich unveränderlich, ein später als fehlend erkanntes Feld ist also eine Formänderung, kein Schalter.

Ein Skalar an der Wurzel — 42, "Text" — wird abgelehnt: Java hat keinen Typalias, es gibt also nichts zu benennen. Ein JSON-Array von Objekten gibt Ihnen den Record seines Elements, und das ist die Form, die Sie tatsächlich an eine List<Root> binden.

Datenschutz ab Werk

Alles läuft lokal in deinem Browser mit JavaScript. Deine Daten werden nie hochgeladen, wodurch das Tool auch für sensible Inhalte sicher ist und offline funktioniert.

Häufige Fragen

Warum `Long` und `Double` statt `long` und `double`?
Weil ein JSON-Feld null sein kann und ein primitiver Typ nicht. `{"score": null}` in ein `double` zu dekodieren wirft entweder oder ergibt stillschweigend 0.0, je nach Bibliothek und Einstellung. Die gepackten Typen machen die Abwesenheit darstellbar — und Generics verlangen sie ohnehin, sobald der Wert in einer `List` landet.
Woher kommt das `@JsonProperty`?
Daher, dass der Schlüssel die Reise nicht übersteht. `content-type` kann kein Komponentenname sein, wird also `contentType` — und Jackson sucht dann nach `contentType` und findet nichts. Die Annotation hält den ursprünglichen Schlüssel fest. Sie fehlte: der Record las das Dokument, aus dem er stammte, stillschweigend nicht mehr. Ein echter Fehler, behoben.
Ich benutze Gson, nicht Jackson. Was ändert sich?
Die Annotation. Gson will `@SerializedName("content-type")` an derselben Stelle, JSON-B will `@JsonbProperty`. Komponentennamen und Typen sind in beiden Fällen gleich — die Annotation und ihren Import zu ersetzen ist die ganze Anpassung.

Ähnliche Konverter