Skip to main content

JSON to Java Class — POJO, record, or Lombok with Jackson / Gson Annotations

JSON to Java POJO, record, or Lombok @Data — paste JSON, get camelCase fields with getters/setters, Jackson @JsonProperty or Gson @SerializedName, nested classes, primitive vs boxed inference.

  • Runs locally
  • Category Developer & DevOps
  • Best for Formatting, validating, shrinking, or inspecting code-adjacent text.
Examples:
How types, annotations & boxing are inferred

Each JSON object becomes a named class (POJO, Lombok @Data, or Java 16+ record) with camelCase fields. When the Java field name differs from the wire key (snake_case, kebab-case), a @JsonProperty (Jackson) or @SerializedName (Gson) annotation preserves the exact key so (de)serialisation round-trips. Integer numbers infer int (or long when they exceed 32-bit range); fractional numbers infer double; a number that is sometimes whole and sometimes fractional widens to double. Arrays of objects fold into ONE class — keys missing from some elements (or seen as null) become OPTIONAL and box to Integer/Long/Double/Boolean, because a Java primitive can never be null. A value that is only ever null types as Object. List generics always box. Turn off "use primitives" to box every scalar.

What this tool does

Paste any JSON payload — a Spring Boot REST response, a Jackson-bound webhook, a Kafka message, a third-party API body — and get back a clean set of Java classes ready to drop into a `.java` file. Choose the shape that fits your codebase: a classic POJO (private fields with generated getters and setters), a Lombok `@Data` class, or a Java 16+ `record`. JSON keys are camelCased into valid Java identifiers (`site_admin` becomes `siteAdmin`, `is-active` becomes `isActive`, `created_at` becomes `createdAt`); whenever the Java field name differs from the wire key, the tool attaches a `@JsonProperty("site_admin")` (Jackson) or `@SerializedName("site_admin")` (Gson) annotation so deserialization binds the original key, not a mangled one. Numbers are split, not flattened: an integer that fits in a 32-bit int infers `int`, a larger integer infers `long`, a fractional value infers `double`, and a field that is sometimes whole and sometimes fractional widens to `double`. The boxing rule is the part most generators get wrong — a Java primitive can never hold null, so any field that is missing in some array element or seen as `null` is forced to its boxed wrapper (`Integer`, `Long`, `Double`, `Boolean`), while required, always-present numbers stay primitive when "use primitives" is on. Arrays of objects fold into ONE shared class, so `[{"a":1},{"a":1,"b":2}]` gives a single type with both fields, not two near-duplicates. Nested objects lift out as their own named classes (`User.address` becomes `UserAddress`), reserved words get a trailing underscore, and only the imports the output needs (`java.util.List`, `lombok.Data`, the annotation package) are emitted. Everything runs in your browser — the JSON never touches a server.

Tool details

Input
Text + Numbers + Structured content
The page exposes text boxes, numeric controls, file pickers, or structured inputs depending on the tool.
Output
Live result + Copy + Download
The result area focuses on usable output, with copy, download, or preview actions when supported.
Privacy
Browser-side processing
The main tool logic does not call an external API, so inputs normally stay in the current tab.
Save / share
Shareable URL state
Key settings are encoded in the URL so another person can reopen the same setup.
Performance budget
Initial JS <= 25 KB
No WASM budget is declared, keeping the tool quick to open on mobile.
Best fit
Developer & DevOps · Developer
Category and role tags drive related tools, internal links, and quick fit checks.

How to use

  1. 1. Input

    Paste or drop your content into the tool panel.

  2. 2. Process

    Click the button. All processing is local in your browser.

  3. 3. Copy / Download

    Copy the result or download to disk in one click.

How JSON to Java Class fits into your work

Use it in the small gaps between coding, reviewing, debugging, and shipping.

Developer jobs

  • Formatting, validating, shrinking, or inspecting code-adjacent text.
  • Preparing snippets for documentation, tickets, commits, or handoff.
  • Checking a small payload quickly without switching tools.

Developer checks

  • Run irreversible transforms like minify or obfuscate on a copy.
  • Keep secrets out of pasted snippets unless the tool explicitly stays local.
  • Use your normal tests or linter before shipping transformed code.

Good next steps

These links move the current task into a more complete workflow.

  1. 1 JSON to C# Class JSON to C# class or record — paste JSON, get PascalCase properties with System.Text.Json or Newtonsoft attributes, nested classes, nullable T?, init setters, DateTime detection. Open
  2. 2 JSON to Go Struct JSON to Go struct — paste JSON, get typed structs with json tags, exported fields, nested sub-structs, pointers for nullable, int64 and omitempty options. Open
  3. 3 JSON to Python Dataclass JSON to Python — paste JSON, get @dataclass or Pydantic v2 models with type hints, Optional inference, nested classes, snake_case fields and aliases. Open

Real-world use cases

  • Type a Spring Boot REST response without hand-writing the model

    You're consuming a third-party API from a Spring service and the response has 25+ fields with snake_case keys. Curl it once, paste the JSON here, set the root name to `OrderResponse`, keep Jackson. Every `created_at`-style key gets a `@JsonProperty` so your `ObjectMapper` binds it, nested objects lift into their own classes, and the optional fields box correctly. Drop the output into `OrderResponse.java`, then `restTemplate.getForObject(url, OrderResponse.class)` returns a fully-typed object instead of a `Map<String, Object>` you have to cast your way through field by field.

  • Generate immutable DTOs with Java records

    A teammate sends a sample request body for the `/orders` endpoint they're building. Paste it, name the root `CreateOrderRequest`, switch the type to `record`. You get a one-line, immutable DTO with value equality and a canonical constructor — no setters to accidentally mutate, no Lombok dependency, and Jackson deserializes records out of the box since 2.12. Paste the response sample too as a second record and both are committed before either of you writes the controller.

  • Keep a Lombok codebase consistent

    Your project already leans on Lombok everywhere. Paste the payload, choose `Lombok @Data`, and you get `@Data`-annotated classes with the `lombok.Data` import — the getters, setters, `equals`, `hashCode`, and `toString` are all generated at compile time, so the source stays as short as the JSON it came from. The new model matches the house style your reviewers expect, with zero boilerplate to scroll past in the PR.

  • Catch which fields are actually optional in a webhook

    A vendor's webhook sometimes includes `cancelled_at` and sometimes omits it. Log a handful of payloads, paste them as a JSON array, and the array-fold detection marks `cancelled_at` as missing in some elements — so it boxes to a wrapper type instead of a primitive that would silently read 0. In your handler a null check now cleanly distinguishes "cancelled" from "still active" instead of guessing whether a default value means the field was absent.

  • Replace a Map<String, Object> with a real type

    Legacy code does `Map<String, Object> data = mapper.readValue(body, Map.class)` and reaches in with casts like `(String) data.get("id")`, losing every compile-time check. Capture one representative response, paste it, generate the class, and replace the map. Now `int`, `long`, and `double` are inferred per field and the compiler catches a renamed key at build time instead of a `ClassCastException` surfacing in prod.

Common pitfalls

  • Pasting a single object and expecting some fields to be boxed (Integer instead of int). A single object has no missing-key signal, so every numeric field is required and stays primitive unless its value is literally null. Optional/boxing inference only kicks in across an array of objects where some elements carry a key and others don't. To explore optionality from one sample, wrap it as `[{...}]`.

  • Leaving a money or precise-decimal field as `double`. The tool infers `double` for any fractional number, but `double` is binary floating point and will misrepresent values like 0.1 or a currency total. For money, hand-edit those fields to `BigDecimal` after generating — JSON carries no signal that a number needs exact base-10 precision.

  • Deleting the @JsonProperty annotation and expecting binding to still work. The annotation is what maps `site_admin` (wire) to `siteAdmin` (field). Remove it and Jackson/Gson will look for a `siteAdmin` key that doesn't exist, leaving the field null. Either keep the annotation or configure a global naming strategy on your mapper instead.

  • Choosing `record` on a pre-Java-16 project. Records are a Java 16 language feature (preview in 14–15). If your build targets Java 11 or 8, the generated `record` won't compile — pick POJO or Lombok for those targets.

Privacy

Your JSON never leaves this browser tab. Parsing and type inference use the browser's built-in `JSON.parse`; there is no network call and no analytics on the textarea content. The Share link encodes your input and the root class name into the URL so a result is reproducible — that means YOU decide when to share. If the payload is sensitive (internal IDs, customer data, prod responses), copy the generated Java instead of sharing the link. Only your option choices (annotation style, POJO/record/Lombok, primitives) are stored in localStorage so your preferred style persists across visits.

FAQ

Tool combos

Folks in your role tend to reach for these alongside this tool.

Made by Toolora · 100% client-side · Updated 2026-06-13