JSON to Java Class
Generate Java records or POJO classes with nested models and optional Jackson annotations
Inferred from samples, not a complete API contract. Missing fields and explicit null are inferred separately but can share an output type; null array elements remain nullable. Duplicate keys and numbers that would change value are rejected.
Limits: 1 MiB, 64 levels, 20,000 values, 200 models and 2,000 model fields. Use strings for exact large IDs or monetary decimals.
Target: Java 17+ with Jackson 2.x. Types are package-private; split into matching files and add public for cross-package use. POJOs expose fields without getters; Jackson mode rejects empty keys. Keys are limited to 16,000 UTF-16 units and records to 254 fields.
After generation, compile in your target project and verify deserialization with representative responses.
About this tool
JSON to Java Class infers Java 17+ records or POJOs with public fields from one object or multiple object samples. Jackson 2.x annotations retain original JSON keys after identifier normalization; disabling them requires a project naming policy or custom mapping. Empty JSON keys are rejected in Jackson mode because JsonProperty("") means the default name, not an empty key. Fields use boxed Long, Double and Boolean types, strings remain String, arrays use List, and incompatible mixed values use Object. Missing and null fields are observed separately but both can become null in the generated Java model; a model does not preserve presence history. Empty POJOs include a serializer marker so Jackson can write an empty object. Types are package-private so a single generated file can contain all declarations. For a public API, split them into matching files and add public where needed. Parsing happens locally within 1 MiB, 64 levels, 20,000 values, 200 models and 2,000 fields, with duplicate-key and numeric-loss checks. Use strings for exact large IDs or decimals. Inference does not select BigDecimal, time classes, enums or validation constraints; compile and deserialize representative responses before using the model. JVM-specific limits also apply: JSON keys have at most 16,000 UTF-16 code units, records have at most 254 fields, and generated identifiers are shortened to 80 characters before uniqueness suffixes. POJO mode avoids the large record constructor.
Scenario Recipes
Compile a record with a conflicting JSON key
Goal: Both original keys remain mapped without generating an illegal record accessor.
- Paste {"getClass":1,"class":2}; select Java record and keep Jackson enabled.
- Generate and inspect the renamed getClassValue and classValue components.
- Compile with Java 17+ and Jackson, then deserialize the original sample and check both values.
Result: Both original keys remain mapped without generating an illegal record accessor.
Failure Clinic (Common Pitfalls)
The generated file compiles but another package cannot see its type
Cause: Package-private types only expose a model inside its package.
Fix: Split each externally used type into its own same-named file, then add public.
A decimal amount becomes Double
Cause: Samples reveal JSON numbers but not a currency contract.
Fix: Represent exact amounts as strings during inference and replace the field with a tested BigDecimal conversion in the application.
Production Snippets
Avoid Object method names in record components
java
// Input: {"getClass":1,"class":2}
record ApiResponse(
@JsonProperty("getClass") Long getClassValue,
@JsonProperty("class") Long classValue
) {}
// Requires import com.fasterxml.jackson.annotation.JsonProperty;Frequently Asked Questions
Which Java and Jackson versions does the output target?
Records require Java 17+ for this workflow. Jackson annotations target 2.x. The tool generates source only; add dependencies in your own project.
Why are generated types package-private?
This permits several top-level models in one file. Split classes into matching files and add public when code outside the package must access them.
Can Jackson map an empty key with JsonProperty?
An empty annotation name selects the default name, so this generator rejects empty JSON keys in Jackson mode. A custom mapping is needed.
Does an optional boxed value preserve absence?
No. A missing value and explicit null can both deserialize to null. Use a separate presence model if this distinction affects patch or update logic.
Keep browsing