100 % locale — i tuoi dati non lasciano mai il tuo browser

JSON in Java — record che Jackson decodifica

Trasforma un campione JSON in record Java. Tipi boxed e annotazione Jackson dove un nome ha dovuto cambiare: il payload si decodifica com’è scritto.

Istantaneo Privato Zero cookie

Input JSON

Output Java

Che cosa fa questo strumento

Un campione JSON diventa record Java, uno per oggetto.

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

public record Address(
    String city
) {}

I record sono il modo più breve di esprimere «dati e nient’altro» nel Java moderno: costruttore, accessori, equals, hashCode e toString vengono con loro. Serve Java 16 o successivo.

La chiave sopravvive al rinomino

Un nome di componente segue le regole di Java: niente trattino, niente cifra iniziale, niente parola riservata. content-type diventa contentType, class diventa class_, 2fa diventa f2fa. Ogni volta che il nome deve cambiare, la chiave originale lo accompagna:

import com.fasterxml.jackson.annotation.JsonProperty;

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

Senza quell’annotazione Jackson cerca contentType e non trova nulla — il record non legge più il documento da cui è stato generato. Mancava fino alla scrittura di questa pagina; il difetto è corretto, e l’annotazione compare solo dove il nome è davvero cambiato, con il suo import.

Tipi wrapper, e perché

Ogni numero è un Long o un Double, ogni booleano un Boolean. JSON ha il null, i primitivi Java no, e un double che riceve un null diventa 0.0 — un valore che non si distingue più da uno zero vero. I tipi wrapper tengono il null rappresentabile, come il formato consente.

Per lo stesso motivo, null e i valori ignoti diventano Object, e un array di essi una List<Object>.

Ciò che un campione non può dire

Nulla è opzionale e nulla porta @Nullable: ogni componente c’è perché il documento lo conteneva. I record sono immutabili in superficie, quindi un campo che deciderai poi possa mancare è un cambio di forma, non un flag.

Uno scalare alla radice — 42, "testo" — è rifiutato: Java non ha alias di tipo, quindi non c’è nulla da nominare. Un array JSON di oggetti ti dà il record del suo elemento, che è la forma che leghi davvero a una List<Root>.

Privato per progettazione

Tutto viene eseguito localmente nel browser con JavaScript. I tuoi dati non vengono mai caricati, quindi lo strumento è sicuro per contenuti sensibili e funziona anche offline.

Domande frequenti

Perché `Long` e `Double` invece di `long` e `double`?
Perché un campo JSON può essere nullo e un primitivo no. Decodificare `{"score": null}` in un `double` solleva un’eccezione o dà 0.0 in silenzio, a seconda della libreria e delle sue impostazioni. I tipi wrapper rendono rappresentabile l’assenza — e sono anche quelli che i generici richiedono se il valore finisce in una `List`.
Da dove viene l’`@JsonProperty`?
Dal fatto che la chiave non sopravvive al viaggio. `content-type` non può essere un nome di componente: diventa `contentType`, e Jackson cerca allora `contentType` nel JSON senza trovare nulla. L’annotazione fissa la chiave originale. Mancava: il record smetteva in silenzio di leggere il documento da cui veniva. Era un difetto vero, corretto.
Uso Gson, non Jackson. Che cosa cambia?
L’annotazione. Gson vuole `@SerializedName("content-type")` nello stesso posto, e JSON-B vuole `@JsonbProperty`. I nomi dei componenti e i tipi sono identici in entrambi i casi: sostituire l’annotazione e il suo import è tutto l’adattamento.

Convertitori correlati