NV ToolkitFormat · Validate · Convert

Code Generators

JSON to Java Converter

Paste a JSON or XML sample — the format is auto-detected — and get typed Java models with names, nesting and nullability inferred for you.

In short

Convert JSON to Java online: paste a sample and generate typed Java models with serialization helpers — powered by quicktype, in your browser.

By NaveenKumar T · Updated

Learn: JSON Examples: From Hello World to Real API Payloads

  • JSON or XML input, auto-detected
  • Nested objects become types
  • Nullability inferred

Runs entirely in your browser — nothing you paste or open here is uploaded, logged, or stored.How we handle data →

Example

Example: JSON order payload to Java

A small order document with a nested object, an array of two items, a decimal total and a null field — enough to show how each Java type, list and nullable is inferred. The same page accepts the XML form of this order too, so the sample below is an example rather than the only accepted format. The right-hand side is the exact output of this tool.

Input · JSON
{
  "id": "ord_9F2KX",
  "status": "processing",
  "paid": true,
  "customer": { "name": "Ada Lovelace", "email": "ada@example.com", "phone": null },
  "items": [
    { "sku": "KB-75", "qty": 1, "price": 149.99 },
    { "sku": "MS-12", "qty": 2, "price": 39.5 }
  ],
  "total": 228.99
}
Generated · Java
// Converter.java

// To use this code, add the following Maven dependency to your project:
//
//
//     com.fasterxml.jackson.core     : jackson-databind          : 2.9.0
//     com.fasterxml.jackson.datatype : jackson-datatype-jsr310   : 2.9.0
//
// Import this package:
//
//     import io.quicktype.Converter;
//
// Then you can deserialize a JSON string with
//
//     Root data = Converter.fromJsonString(jsonString);

package io.quicktype;

import java.io.IOException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import java.util.*;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;

public class Converter {
    // Date-time helpers

    private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
            .appendOptional(DateTimeFormatter.ISO_DATE_TIME)
            .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
            .appendOptional(DateTimeFormatter.ISO_INSTANT)
            .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SX"))
            .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssX"))
            .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
            .toFormatter()
            .withZone(ZoneOffset.UTC);

    public static OffsetDateTime parseDateTimeString(String str) {
        return ZonedDateTime.from(Converter.DATE_TIME_FORMATTER.parse(str)).toOffsetDateTime();
    }

    private static final DateTimeFormatter TIME_FORMATTER = new DateTimeFormatterBuilder()
            .appendOptional(DateTimeFormatter.ISO_TIME)
            .appendOptional(DateTimeFormatter.ISO_OFFSET_TIME)
            .parseDefaulting(ChronoField.YEAR, 2020)
            .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
            .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
            .toFormatter()
            .withZone(ZoneOffset.UTC);

    public static OffsetTime parseTimeString(String str) {
        return ZonedDateTime.from(Converter.TIME_FORMATTER.parse(str)).toOffsetDateTime().toOffsetTime();
    }
    // Serialize/deserialize helpers

    public static Root fromJsonString(String json) throws IOException {
        return getObjectReader().readValue(json);
    }

    public static String toJsonString(Root obj) throws JsonProcessingException {
        return getObjectWriter().writeValueAsString(obj);
    }

    private static ObjectReader reader;
    private static ObjectWriter writer;

    private static void instantiateMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.findAndRegisterModules();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        SimpleModule module = new SimpleModule();
        module.addDeserializer(OffsetDateTime.class, new JsonDeserializer<OffsetDateTime>() {
            @Override
            public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
                String value = jsonParser.getText();
                return Converter.parseDateTimeString(value);
            }
        });
        mapper.registerModule(module);
        reader = mapper.readerFor(Root.class);
        writer = mapper.writerFor(Root.class);
    }

    private static ObjectReader getObjectReader() {
        if (reader == null) instantiateMapper();
        return reader;
    }

    private static ObjectWriter getObjectWriter() {
        if (writer == null) instantiateMapper();
        return writer;
    }
}

// Root.java

package io.quicktype;

import com.fasterxml.jackson.annotation.*;

public class Root {
    private String id;
    private String status;
    private boolean paid;
    private Customer customer;
    private Item[] items;
    private double total;

    @JsonProperty("id")
    public String getID() { return id; }
    @JsonProperty("id")
    public void setID(String value) { this.id = value; }

    @JsonProperty("status")
    public String getStatus() { return status; }
    @JsonProperty("status")
    public void setStatus(String value) { this.status = value; }

    @JsonProperty("paid")
    public boolean getPaid() { return paid; }
    @JsonProperty("paid")
    public void setPaid(boolean value) { this.paid = value; }

    @JsonProperty("customer")
    public Customer getCustomer() { return customer; }
    @JsonProperty("customer")
    public void setCustomer(Customer value) { this.customer = value; }

    @JsonProperty("items")
    public Item[] getItems() { return items; }
    @JsonProperty("items")
    public void setItems(Item[] value) { this.items = value; }

    @JsonProperty("total")
    public double getTotal() { return total; }
    @JsonProperty("total")
    public void setTotal(double value) { this.total = value; }
}

// Customer.java

package io.quicktype;

import com.fasterxml.jackson.annotation.*;

public class Customer {
    private String name;
    private String email;
    private Object phone;

    @JsonProperty("name")
    public String getName() { return name; }
    @JsonProperty("name")
    public void setName(String value) { this.name = value; }

    @JsonProperty("email")
    public String getEmail() { return email; }
    @JsonProperty("email")
    public void setEmail(String value) { this.email = value; }

    @JsonProperty("phone")
    public Object getPhone() { return phone; }
    @JsonProperty("phone")
    public void setPhone(Object value) { this.phone = value; }
}

// Item.java

package io.quicktype;

import com.fasterxml.jackson.annotation.*;

public class Item {
    private String sku;
    private long qty;
    private double price;

    @JsonProperty("sku")
    public String getSku() { return sku; }
    @JsonProperty("sku")
    public void setSku(String value) { this.sku = value; }

    @JsonProperty("qty")
    public long getQty() { return qty; }
    @JsonProperty("qty")
    public void setQty(long value) { this.qty = value; }

    @JsonProperty("price")
    public double getPrice() { return price; }
    @JsonProperty("price")
    public void setPrice(double value) { this.price = value; }
}

Look for the "phone" field: sampled as null, it is typed as Object. "items" became Item[], and "total" is double.

Learn more

From JSON sample to Java types

Hand-writing model classes from a JSON payload is transcription work: read a field, type a property, repeat eighty times, miss one. This page runs quicktype (the same engine behind the best-known generators) against your document, merging array elements to find the common shape and naming nested types from their keys.

Decimals become double, so total is 228.99000000000001 the first time you add two of them together. For prices, swap the generated double for BigDecimal and enable USE_BIG_DECIMAL_FOR_FLOATS on the ObjectMapper the Converter builds; the @JsonProperty annotations stay exactly as they are. Integers are safe as they stand — quicktype types them long, which holds a 64-bit ID exactly.

How JSON values become Java types

Inference works from the values in your sample. Strings map to String, integers and decimals are told apart (228.99 becomes double, while 1 and 2 stay integral), true/false become the language's boolean, and an object such as "customer" becomes its own named type. The "items" array is typed as Item[] because every element shares the same keys — quicktype unifies the shapes of all array elements into one Item type.

Nulls are the one place inference needs your help: "phone": null carries no type information, so the field is emitted as Object. If the real API sometimes sends a string there, include a sample where the field is populated (paste several documents merged into one array) and the generated type becomes the union of what it saw.

Pasting XML works here too — a sample starting with "<" is parsed before inference runs — but if XML is your usual input, XML to Java is the page written for it: same generator, with the element-versus-attribute typing rules and a worked XML example.

Annotations, nulls and nested arrays in the generated Java

Every getter and setter carries a Jackson @JsonProperty naming the wire key, and each class imports com.fasterxml.jackson.annotation.* — there is no Gson @SerializedName and no Moshi annotation anywhere. The separate Converter class does the rest: it builds an ObjectMapper with FAIL_ON_UNKNOWN_PROPERTIES turned off and WRITE_DATES_AS_TIMESTAMPS disabled, registers a JSR-310 module with a lenient date-time formatter, and caches an ObjectReader and ObjectWriter. Because the annotation pins the wire name, you can rename the Java property freely: order_id becomes getOrderID and still serializes as order_id.

A field whose only sampled value is null has no type to infer, so Java gets a property of type Object — legal, but it hands the cast back to you. Paste a second document where the field carries a value and the two samples unify: the property becomes String, a reference type, so null still round-trips. A key that is absent from one of several merged samples behaves the same way and arrives boxed — Long or Boolean rather than long or boolean — so absence stays representable instead of silently becoming zero.

Nested objects become their own top-level classes named after the key: customer becomes Customer, in its own // Customer.java section of the single output file, so split the file on those markers before compiling. Arrays of objects unify into one Item class and are typed Item[], a Java array rather than a List. Two traps come from the sample rather than the language: an array with a single element still names the type but proves nothing about optional fields, and an empty array carries no element type at all, so you get Object[] and no class.

Help

Frequently asked questions

Everything you need to know about the JSON to Java.

01How do I generate Java classes from JSON?

Paste a representative document — JSON or XML, the format is detected automatically — and press Convert. A real API response works best. Nested objects become their own Java types, arrays become Item[], and the result downloads as Root.java.

02What does the generated Java code include?

Generated Java arrives as POJO classes with private fields, getters and setters, plus Jackson-style converter helpers for serialization — drop them into any Maven/Gradle project and deserialize the payload immediately.

03How do I use the generated Java code in my project?

Add jackson-databind (2.9 or newer) to your Maven or Gradle build and drop the generated classes into a package. Converter.fromJsonString(json) parses a JSON string into Root and Converter.toJsonString(root) serializes it back. Fields are private with getters and setters, and every property carries a @JsonProperty annotation so the wire names survive any renaming.

04Which JSON library does the generated Java use?

The classes themselves are plain POJOs usable with any library; the included converter helper targets Jackson (the de-facto standard). Using Gson or Moshi? Keep the classes, swap the converter — annotations are minimal by design.

Keep working

Related tools

Learn the format

Related guides

All guides →