JSON to Java POJO

Generate Java POJO classes from JSON instantly. Supports Jackson, Gson, and Lombok annotations. Handles nested objects, arrays, and custom root class names. Free, runs in your browser.

  • Runs in your browser
  • Your data never leaves your browser
  • Free · No Sign-Up
A blank name uses RootObject. Changing the name generates again after 300 ms.
Annotation Choose None, Jackson, Gson or Lombok (@Data). Changing the annotation generates again immediately.
Replace JSON with a sample containing nested objects, arrays and null, then generate immediately with the current settings.
Clear JSON, output and status. Keep the root name and the selected mode. Ctrl/⌘+L with focus in the tool also clears the root name.
Enter valid JSON without comments or trailing commas. Generation runs 300 ms after typing stops; invalid JSON clears the output and shows an error.
Java Output
Copy the complete displayed Java output. Empty output is not copied.

Enter JSON or load the example to generate Java.

Examples, details and FAQ Worked examples, how it compares with other tools, and answers to common questions.

Type Mapping

  • null → Object
  • string → String
  • integer number → int; outside −2,147,483,648 to 2,147,483,647 → long
  • a field whose samples mix integers and decimals → the wider type (double); other mixes → Object
  • floating-point number → double
  • boolean → boolean
  • array → List<T>
  • nested object → separate public class

Example

Given this JSON:

{"user": {"first_name": "Alice", "age": 30}, "tags": ["admin"]}

The tool generates (Lombok mode):

import java.util.List;
import lombok.Data;

@Data
public class RootObject {
    private User user;
    private List<String> tags;
}

@Data
public class User {
    private String firstName;
    private int age;
}

Example: Order With Nested Items (Jackson Mode)

Input:

{"order_id": 9007, "customer": {"name": "Alice", "vip": true}, "items": [{"sku": "A-1", "qty": 2, "price": 9.5}, {"sku": "B-2", "qty": 1, "price": 20}], "note": null}

Output (getters and setters shortened):

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

public class RootObject {
  @JsonProperty("order_id")
  private int orderId;
  private Customer customer;
  private List<ItemsItem> items;
  private Object note;
  // getters and setters omitted here
}

public class Customer {
  private String name;
  private boolean vip;
  // ...
}

public class ItemsItem {
  private String sku;
  private int qty;
  private double price;
  // ...
}

Javac rejects this output as one file: each public class must live in a file of the same name. Split it into RootObject.java, Customer.java and ItemsItem.java; the “No annotations” output then compiles with javac 21 as is.

Classes come out in the order they are first met: the root class, then each nested class. Array elements that are objects are merged into one class named after the key plus Item (items → ItemsItem); a field that appears only in some elements is still included, so the class covers every sample.

What to Check After Generating

  • price is double: the first item has 9.5 and the second 20, and the tool widens int and double to double. For money, change it to BigDecimal; a binary double cannot hold 0.1 exactly.
  • null in the sample becomes Object. Replace it with the real type.
  • A whole number outside the int range in the sample, such as the millisecond timestamp 1730000000000, becomes long. If the sample has a small ID that can grow later, change int to long yourself.
  • Lombok mode does not add @JsonProperty, so order_id no longer maps to orderId:
import java.util.List;
import lombok.Data;

@Data
public class RootObject {
  private int orderId;
  private Customer customer;
  private List<ItemsItem> items;
  private Object note;
}

In Lombok mode either add @JsonProperty yourself or configure Jackson with PropertyNamingStrategies.SNAKE_CASE. Gson mode uses @SerializedName for the same purpose.

Reading the JSON with Jackson:

ObjectMapper mapper = new ObjectMapper();
RootObject order = mapper.readValue(json, RootObject.class);

On Java 16 and later, a small immutable model can be a record instead of a class; Jackson 2.12+ reads records:

public record Customer(String name, boolean vip) {}

Example: Same Key With Two Shapes, and Keys Java Cannot Use (Jackson Mode)

{"billing": {"address": {"city": "Paris"}}, "shipping": {"address": {"line1": "1 Main St"}}, "class": "A", "2fa": true, "URL": "https://example.com"}

Output (most accessors omitted):

import com.fasterxml.jackson.annotation.JsonProperty;

public class RootObject {
  private Billing billing;
  private Shipping shipping;
  @JsonProperty("class")
  private String classValue;
  @JsonProperty("2fa")
  private boolean t2fa;
  @JsonProperty("URL")
  private String uRL;

  @JsonProperty("URL")
  public String getURL() {
  // other getters and setters omitted here
}

public class Address {
  private String city;
  // ...
}

public class ShippingAddress {
  private String line1;
  // ...
}
  • The two address objects have different fields, so the second gets the parent name as a prefix (ShippingAddress). Objects with the same fields and types share one class; if the prefixed name is also taken, a number is added.
  • Java keywords and literals get Value (class → classValue), a name that would start with a digit gets T (2fa → t2fa), and keys that become the same name get a number (first-name and first_name → firstName and firstName2). The annotation keeps the original key.
  • Jackson names the accessor getURL() url, not uRL. Without the annotation on the getter and setter, Jackson would see a second property and fail on the key URL. Gson reads fields only and needs no such annotation.

With javac 21, Jackson 2.17.2 and Gson 2.11.0, each Jackson and Gson output in the tool’s test compiles and reads its sample back to the same JSON; each Lombok 1.18.34 output compiles.

Limits

  • None and Lombok modes keep only the Java name. classValue and t2fa do not map to class and 2fa there. Use Jackson or Gson mode when keys are not valid Java names.
  • Jackson cannot write an empty key. @JsonProperty("") means “use the default name”, so for the key "" the tool writes @JsonAlias("") and a comment. Jackson then reads {"": 4}, but writes it back as {"t": 4}. Gson writes @SerializedName("") and keeps the key.
  • Primitive types cannot be null. int, long, double and boolean fields read a missing or null value as 0 or false with Jackson’s default settings. Use Integer, Long and so on when absence matters.
  • A root array of primitives such as [1, 2] generates no class; the output is the comment // Array of primitives — no class to generate.
  • Lombok mode adds only @Data. It writes no @JsonProperty or @SerializedName, so snake_case keys need a naming strategy or hand-added annotations, as shown above.

For the same JSON as Kotlin or TypeScript types, use the JSON to Kotlin or JSON to TypeScript generator.

FAQ

What does this tool generate?

It generates Java POJO (Plain Old Java Object) classes from JSON. Each nested object becomes its own named public class with private fields and getter/setter methods (or @Data with Lombok).

What annotation modes are supported?

Four modes: None (pure POJO with getters/setters), Jackson (@JsonProperty), Gson (@SerializedName), and Lombok (@Data). Jackson and Gson modes annotate a field when its JSON key differs from the field name. Jackson mode also annotates the getter and setter when Jackson would derive another name from them (getURL is read as url). None and Lombok modes keep no original key.

How are JSON types mapped to Java types?

string → String, integer → int (long when the value is outside the int range), float/double → double, a field that mixes int and double samples → double, boolean → boolean, null → Object, array → List<T>, nested object → separate class.

When is the List import added?

import java.util.List is automatically included whenever an array field is present in the output.

Is my data sent to a server?

No. The entire conversion runs in your browser. No data leaves your machine.