JSON to Java POJO Generator

Generate Java POJO classes from JSON with Jackson annotations, nested classes, List support, and Optional types.

What is JSON to Java POJO Generator?

Java's object-oriented model requires a Plain Old Java Object (POJO) for each JSON shape you consume: a class with private fields, public getters and setters, and a constructor. Writing these by hand for a deeply nested API response is repetitive and fragile — one mistyped field name or missing getter breaks deserialization silently when using Jackson's ObjectMapper. Jackson is the de-facto standard for JSON in Java. It maps JSON keys to Java fields using naming conventions or explicit @JsonProperty annotations. For Spring Boot applications, Jackson is bundled and preconfigured; a properly annotated POJO works out of the box with @RequestBody and ResponseEntity<T>. This generator produces Jackson-ready POJOs with correct types, nested class ordering (inner classes before outer), optional getters/setters, and Optional<T> for nullable fields.

How to Use

  1. Set the root class name to match the response concept (e.g. "UserProfile", "InvoiceResponse") — this becomes the outermost Java class
  2. Enable "Jackson annotations" to add @JsonProperty on every field — required when JSON keys use snake_case or other conventions that differ from Java camelCase field names
  3. Enable "Detect dates" to map ISO-8601 strings to java.time.Instant or java.time.LocalDate instead of String — requires Java 8+ and the jackson-datatype-jsr310 module
  4. Enable "Optional" to wrap nullable fields in Optional<T> — useful for explicit null handling, though Jackson needs registerModule(new Jdk8Module()) to serialize/deserialize Optional correctly
  5. Enable "Getters/Setters" to generate full getter and setter methods — required for Jackson's default property-based serialization mode
  6. Paste your JSON and click "Generate Java POJO" — copy the output into your .java file

Why Use This Tool?

Generates complete POJOs with private fields, constructors, getters, and setters — ready to drop into a Spring Boot controller
@JsonProperty annotations bridge the gap between snake_case JSON keys and camelCase Java field names without a custom NamingStrategy
Nested classes are ordered top-to-bottom with children first, matching Jackson's requirement for static inner class or separate file layout
List<T> for JSON arrays with type inference from the first element
java.time.Instant and java.time.LocalDate support for ISO-8601 date strings (with jackson-datatype-jsr310)
Runs entirely in the browser — your API response data never leaves your device

Tips & Best Practices

  • For Spring Boot, add @JsonInclude(JsonInclude.Include.NON_NULL) at the class level to omit null fields from the response JSON — cleaner than returning "field": null for every absent field
  • If you use Lombok, you can replace the generated constructors, getters, and setters with @Data or @Value annotations — the generated field declarations are compatible with Lombok without modification
  • For dates, register the JSR-310 module: ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()) — without this, Jackson cannot deserialize Instant or LocalDate
  • Java's Optional<T> is designed for return values, not for fields — consider using @Nullable (from javax.annotation) for fields and leaving Optional for method return types in service layers
  • Jackson's default behavior for unknown fields is to throw an exception — add @JsonIgnoreProperties(ignoreUnknown = true) at the class level in production code to handle API additions gracefully

Frequently Asked Questions

What is the complete JSON type → Java type mapping?

JSON string → String (or Instant/LocalDate with date detection). JSON integer → Integer (or Long for values exceeding Integer.MAX_VALUE). JSON float → Double. JSON boolean → Boolean. JSON null → the same type as inferred, or Optional<T> if that option is enabled. JSON array → List<T> with T inferred from the first element. JSON object → a separate POJO class. Heterogeneous arrays → List<Object>.

What is Jackson and why is it standard for Java JSON?

Jackson is the most widely used JSON library in the Java ecosystem. It is bundled with Spring Boot by default and used by Micronaut, Quarkus, and most Java REST frameworks. Jackson's ObjectMapper can serialize and deserialize Java objects to/from JSON with no configuration for standard types. @JsonProperty annotations are needed when the JSON key names do not match Java's camelCase convention or when field names are Java reserved words.

Should I use Optional<T> for nullable fields?

Optional<T> is useful for making nullability explicit at the API level — callers must call .orElse() or .orElseThrow() rather than risking a NullPointerException. However, Jackson requires the Jdk8Module to handle Optional: mapper.registerModule(new Jdk8Module()). In Spring Boot, this module is auto-registered. For simple internal POJOs or when Jackson is not configured with the Jdk8Module, use nullable reference types (String field = null) instead.

Should I use records instead of POJOs for Java 16+?

Java records (record UserProfile(String id, String name) {...}) are immutable value types with auto-generated equals, hashCode, and accessors — cleaner than POJOs for read-only API responses. Jackson 2.12+ supports records directly without any annotations for simple cases. The generator outputs traditional POJOs for maximum compatibility, but if you are on Java 16+, converting the output to a record is straightforward.

Is my data sent to a server?

No. All code generation runs entirely in your browser. Your JSON data never leaves your device.

Real-world Examples

Spring Boot REST controller request/response model

A typical Spring Boot endpoint receives a JSON request body and returns a JSON response. The generated POJO with Jackson annotations works directly as a @RequestBody parameter — Spring Boot auto-configures Jackson to use the annotations.

Input
{
  "orderId": "ord_2291",
  "customerId": "cust_0091",
  "status": "pending",
  "totalAmount": 149.99,
  "currency": "USD",
  "createdAt": "2024-07-15T14:30:00Z",
  "shippingAddress": {
    "line1": "456 Oak Ave",
    "city": "Portland",
    "state": "OR",
    "zipCode": "97201",
    "country": "US"
  },
  "items": []
}
Output
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.time.Instant;
import java.util.List;

@JsonIgnoreProperties(ignoreUnknown = true)
public class ShippingAddress {
    @JsonProperty("line1") private String line1;
    @JsonProperty("city") private String city;
    @JsonProperty("state") private String state;
    @JsonProperty("zipCode") private String zipCode;
    @JsonProperty("country") private String country;

    // getters and setters omitted for brevity
}

@JsonIgnoreProperties(ignoreUnknown = true)
public class Order {
    @JsonProperty("orderId") private String orderId;
    @JsonProperty("customerId") private String customerId;
    @JsonProperty("status") private String status;
    @JsonProperty("totalAmount") private Double totalAmount;
    @JsonProperty("currency") private String currency;
    @JsonProperty("createdAt") private Instant createdAt;
    @JsonProperty("shippingAddress") private ShippingAddress shippingAddress;
    @JsonProperty("items") private List<Object> items;

    // getters and setters omitted for brevity
}

Handling a nullable payment method in an invoice

Some invoices have a payment method attached; others are in draft state and the field is null. Using Optional<PaymentMethod> makes the nullability explicit and prevents NullPointerException without null checks.

Input
{
  "invoiceId": "inv_0552",
  "amount": 2500,
  "dueDate": "2024-08-01",
  "isPaid": false,
  "paymentMethod": null,
  "notes": "Net 30 terms"
}
Output
import com.fasterxml.jackson.annotation.JsonProperty;
import java.time.LocalDate;
import java.util.Optional;

public class PaymentMethod {}

public class Invoice {
    @JsonProperty("invoiceId") private String invoiceId;
    @JsonProperty("amount") private Integer amount;
    @JsonProperty("dueDate") private LocalDate dueDate;
    @JsonProperty("isPaid") private Boolean isPaid;
    @JsonProperty("paymentMethod") private Optional<PaymentMethod> paymentMethod;
    @JsonProperty("notes") private String notes;

    // Requires: mapper.registerModule(new Jdk8Module());
}

Related Tools