JSON to Java Class (POJO) Generator
Turn JSON into Lombok @Data classes: nested objects become their own classes, snake_case keys become camelCase fields, and @JsonProperty keeps Jackson binding.
Before Jackson can deserialize a response you have to write the POJO by hand: camelCase the field names, add getters and setters, remember @JsonProperty for every underscore key. On a payload with thirty fields that is a real chunk of an afternoon, and one missing annotation shows up later as a null field at runtime. Paste the JSON and you get @Data classes with nested objects split into their own classes and the annotations already in place.
The whole conversion happens in the browser and the code is never uploaded, so field names from internal services stay on your machine. What comes back is a structural skeleton: no package declaration, no business annotations, no validation rules. Numeric types and date handling still need a decision from you, and the sections below point out where the generator defaults are worth overriding.
What the generator emits
Every object in the JSON, nested ones included, becomes its own class. The class name is the key converted to PascalCase, and the root class is called RootModel unless you type another name into Root type name in the toolbar. Classes carry @Data and nothing else — no @Builder, @NoArgsConstructor or @AllArgsConstructor — and there is no package statement, so you add the package line yourself. Three imports are always written: lombok.Data, com.fasterxml.jackson.annotation.JsonProperty and java.util.List; the List import appears even when the payload has no arrays, so delete it if it is unused. Jackson needs a no-argument constructor, which @Data provides as long as the class has no final fields. If your team does not use Lombok, write the getters, setters and explicit constructor yourself.
Field types and numeric traps
Whole numbers become Integer, decimals Double, booleans Boolean, and strings String. null becomes Object, so the boxed reference still needs a null check on your side, and an empty array becomes List<Object>. The generator does not distinguish Long from BigDecimal: an order number or snowflake ID above 2,147,483,647 is typed Integer and can overflow during deserialization, and money typed Double introduces rounding error. Change those fields to Long or BigDecimal by hand. Dates and timestamps are typed String, because inference looks only at the JSON value and not at the field name or its format; switching to LocalDateTime or Date means editing the type and making sure your Jackson time configuration matches.
Naming collisions and annotations
Field names are converted to camelCase: an underscore or hyphen marks the next letter for upper case, so user_name and user-name both become userName. A @JsonProperty annotation is added only when the generated field name differs from the key, and it always carries the original key so Jackson keeps binding. The collision is the trap: if one object contains both user_name and user-name, both normalize to userName, two identical fields are emitted and the file does not compile. Keys with dots or spaces produce illegal identifiers, and non-ASCII keys are legal Java but better avoided in a DTO. Fix the keys in the JSON or delete one of the duplicate fields — the generator cannot choose for you.
Frequently asked questions
- Which dependencies does the generated code need?
- Lombok for @Data, which supplies getters, setters, toString and the default constructor, and jackson-annotations for @JsonProperty. Both imports are in the output, but the dependencies have to be added to your pom.xml or build.gradle. If Lombok is banned in your project, replace @Data with hand-written accessors and an explicit no-argument constructor, since Jackson needs one.
- Why is a timestamp field typed String instead of LocalDateTime or Date?
- Because inference looks only at the JSON value, and in JSON a timestamp is a string. There is no field-name or format detection, so every date-like value becomes String and Jackson binds the text as it is. Change the type manually and check your ObjectMapper time settings; LocalDateTime also needs jackson-datatype-jsr310 on the classpath.
- Why does the generated file fail to compile with duplicate fields?
- Two different keys can normalize to the same Java field name. user_name and user-name both become userName, and mixing snake_case with camelCase in one object does the same. Rename the keys in the JSON — the API contract is the only place where the original spelling matters — or delete one of the fields after generating.
- How are arrays and nested objects handled?
- A nested object becomes a separate class and the field type points at it. An array becomes List<T>, where T is inferred from the first element: empty arrays give List<Object>, and objects inside arrays get their own classes. Fill in the generic by hand once you know the real element type, otherwise every read needs a cast.