Skip to content

JSON to Java

Generate Java POJOs from a JSON sample.

Input

What this tool does

Generate Java POJOs with Jackson annotations from a JSON sample. Use the package option to set the generated package declaration so the file drops straight into your source tree. Each nested object becomes its own class. Powered by quicktype, runs entirely in your browser.

How to use it

Paste JSON (or load the example) and read the Java POJOs on the right. Set the package name in the options pane to match your source tree; default output uses Jackson @JsonProperty annotations on public fields.

Input: {"id":42,"name":"devsmiths","createdAt":"2024-03-11T08:24:00Z","stars":1280,"public":true,"contributors":[{"login":"ada","commits":51,"admin":true},{"login":"linus","commits":33,"admin":false}],"homepage":null}

Output (Java):

package com.devsmiths;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

public class Root {
    @JsonProperty("id") public long id;
    @JsonProperty("name") public String name;
    @JsonProperty("createdAt") public String createdAt;
    @JsonProperty("stars") public long stars;
    @JsonProperty("public") public boolean isPublic;
    @JsonProperty("contributors") public List<Contributor> contributors;
    @JsonProperty("homepage") public Object homepage;
}

public class Contributor {
    @JsonProperty("login") public String login;
    @JsonProperty("commits") public long commits;
    @JsonProperty("admin") public boolean admin;
}

Limits and edge cases

  • Default output uses Jackson annotations (@JsonProperty on public fields). For Gson, find/replace @JsonProperty @SerializedName and adjust imports — the field shapes are otherwise compatible.
  • Fields are public, not private with getters/setters. This is intentional — modern Jackson and Gson read public fields directly and the generator avoids the Lombok dependency. Add @lombok.Data manually if you want a builder; the generator stays Lombok-free.
  • Reserved Java keywords as JSON keys (class, public) are renamed to className / isPublic with the original preserved in the @JsonProperty tag. The reverse direction works because the tag drives serialization.
  • Whole numbers are typed as long regardless of magnitude. For IDs that fit in int, tighten by hand. Jackson tolerates either at decode time.
  • Date strings stay as String, not java.time.Instant. ISO 8601 strings are unambiguous; add an @JsonDeserialize(using = InstantDeserializer.class) for typed dates.
  • Arrays are emitted as List<T> from java.util. Replace with T[] by hand if primitive efficiency matters more than .add() ergonomics.

Frequently asked questions

Jackson, Gson, or javax.json — which annotations are generated?
Jackson (`@JsonProperty`). It's the dominant library in 2026 — Spring uses it by default, Quarkus and Micronaut both ship Jackson out of the box. For Gson, find/replace `@JsonProperty` → `@SerializedName` and adjust the import. javax.json (now jakarta.json) uses a streaming API that doesn't map cleanly to POJO field annotations; pick a different library if you need stream-based parsing.
Why public fields instead of private + getters/setters?
To avoid the boilerplate. Public fields work with Jackson and Gson directly (both reflect over fields by default); private fields without accessors don't, and adding 50 lines of getters/setters per POJO is what Lombok exists to avoid. The generator stays Lombok-free so the output works without adding a dependency. Add `@lombok.Data` and switch fields to private by hand if you have Lombok already.
How do I handle JSON keys that collide with Java keywords (public, class)?
Renamed with a prefix (`isPublic`, `className`) and the original preserved in the `@JsonProperty` value. The serializer reads/writes the original key; your Java code uses the rename. For Boolean fields, the rename uses `is` prefix conventionally — both Jackson and Gson recognise the `is` boolean accessor pattern.
Why long for whole numbers and not int?
Because Java's int is 32-bit and JSON numbers (via JavaScript) are 64-bit doubles — a 2^31+ JSON integer would silently overflow int. long is safe for everything up to 2^53; beyond that, the precision loss happens before the JSON reaches your Java decoder anyway. Tighten to int by hand for fields you know fit.
Can the generator emit immutable records (Java 14+ records)?
Not by default. Java records would be cleaner but require Jackson's `@JsonCreator` + ordered constructor parameters to round-trip — fragile to refactor. The generator emits mutable POJOs because they round-trip with zero ceremony. Convert by hand: `public class Root` → `public record Root(@JsonProperty("id") long id, ...)` plus `@JsonCreator` if you have non-trivial fields.
How do I parse JSON with the generated POJOs?
With Jackson: `new ObjectMapper().readValue(jsonString, Root.class)`. With Gson: `new Gson().fromJson(jsonString, Root.class)`. Both read public fields and `@JsonProperty` / `@SerializedName` annotations correctly. For Spring Boot, the `ObjectMapper` is autowired — inject it instead of constructing a new one per request.

Content reviewed by