100 % local — seus dados nunca saem do seu navegador

JSON para Java — records que o Jackson decodifica

Transforme uma amostra JSON em records Java. Tipos empacotados e anotação Jackson onde um nome teve de mudar: o payload decodifica como foi escrito.

Instantâneo Privado Zero cookies

Entrada JSON

Saída Java

O que esta ferramenta faz

Uma amostra JSON vira records Java, um por objeto.

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

public record Address(
    String city
) {}

Os records são o jeito mais curto de dizer «dados e nada mais» no Java moderno: construtor, acessores, equals, hashCode e toString vêm junto. É preciso Java 16 ou posterior.

A chave sobrevive ao renome

Um nome de componente segue as regras do Java: sem hífen, sem dígito inicial, sem palavra reservada. content-type vira contentType, class vira class_, 2fa vira f2fa. Toda vez que o nome precisa mudar, a chave original vai junto:

import com.fasterxml.jackson.annotation.JsonProperty;

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

Sem essa anotação, o Jackson procura contentType e não acha nada — o record não lê mais o documento de onde foi gerado. Ela faltava até esta página ser escrita; o defeito está corrigido, e a anotação só aparece onde o nome realmente mudou, com o seu import.

Tipos empacotados, e por quê

Todo número é um Long ou um Double, todo booleano um Boolean. O JSON tem null, os primitivos do Java não, e um double que recebe um null vira 0.0 — um valor que não se distingue de um zero de verdade. Os tipos empacotados mantêm o null representável, que é o que o formato permite.

Pela mesma razão, null e os valores desconhecidos viram Object, e um array deles vira List<Object>.

O que uma amostra não consegue dizer

Nada é opcional e nada leva @Nullable: cada componente está ali porque o documento o trazia. Os records são imutáveis na superfície, então um campo que você depois decidir que pode faltar é mudança de forma, não uma flag.

Um escalar na raiz — 42, "texto" — é recusado: o Java não tem alias de tipo, então não há o que nomear. Um array JSON de objetos devolve o record do seu elemento, que é a forma que você de fato liga a uma List<Root>.

Privado por padrão

Tudo é executado localmente no seu navegador com JavaScript. Os seus dados nunca são enviados para um servidor, o que torna a ferramenta segura para conteúdo sensível e funciona offline.

Perguntas frequentes

Por que `Long` e `Double` e não `long` e `double`?
Porque um campo JSON pode ser nulo e um primitivo não. Decodificar `{"score": null}` num `double` lança exceção ou dá 0.0 em silêncio, conforme a biblioteca e seus ajustes. Os tipos empacotados tornam a ausência representável — e são também os que os genéricos exigem se o valor for parar numa `List`.
De onde vem o `@JsonProperty`?
Do fato de a chave não sobreviver à viagem. `content-type` não pode ser nome de componente: vira `contentType`, e o Jackson passa a procurar `contentType` no JSON sem achar nada. A anotação fixa a chave original. Ela faltava: o record deixava de ler, em silêncio, o documento de onde veio. Era um defeito real, corrigido.
Eu uso Gson, não Jackson. O que muda?
A anotação. O Gson quer `@SerializedName("content-type")` no mesmo lugar, e o JSON-B quer `@JsonbProperty`. Os nomes de componente e os tipos são idênticos nos dois casos: trocar a anotação e o seu import é toda a adaptação.

Conversores relacionados