JSON to Java
Java POJO-klassen genereren vanuit JSON
JSON-invoer
Java-uitvoer
Wat is JSON naar Java-klasse-conversie?
JSON naar Java-klasse-conversie zet een ruwe JSON-object om in Plain Old Java Object (POJO)-definities met private velden, getters en setters. Java heeft geen ingebouwd JSON-typesysteem, dus elke JSON API-response, configuratiebestand of berichtpayload heeft een bijbehorende klasse nodig voordat je er op een type-veilige manier mee kunt werken. Bibliotheken zoals Jackson en Gson koppelen JSON-sleutels aan Java-velden via reflectie, maar ze vereisen dat de klassedefinities al bestaan.
Een standaard Java POJO voor JSON-deserialisatie declareert een private veld voor elke JSON-sleutel, een constructor zonder argumenten en een getter/setter-paar per veld. Geneste JSON-objecten worden afzonderlijke klassen. Arrays worden List<T>-velden met een java.util.List-import. Primitieve JSON-typen mappen naar Java-primitieven (int, double, boolean) of hun wrapper-typen (Integer, Double, Boolean) bij gebruik in generics. Null-waarden mappen doorgaans naar Object of een nullable referentietype.
Deze klassedefinities met de hand schrijven is repetitief. Je leest elke JSON-sleutel, bepaalt het Java-type op basis van de waarde, converteert naamgevingsconventies van camelCase JSON naar camelCase Java-velden, maakt PascalCase-klassenamen voor geneste objecten en voegt de getter/setter-boilerplate toe. Voor een JSON-object met 15 velden en 3 geneste objecten betekent dat het schrijven van 4 klassen, 30+ methoden en alles consistent houden. Een converter doet dit in milliseconden.
Waarom een JSON naar Java-converter gebruiken?
Java POJO's handmatig aanmaken vanuit JSON betekent elk veld inspecteren, typen afleiden uit voorbeeldwaarden, getter/setter-paren schrijven en het proces herhalen voor elk genest object. Wanneer het API-contract verandert, update je alles met de hand. Een converter neemt dat mechanische werk weg.
JSON naar Java-toepassingen
JSON naar Java type-mapping
Elke JSON-waarde mapt naar een specifiek Java-type. De onderstaande tabel toont hoe de converter elk JSON-type vertaalt naar zijn Java-equivalent. De kolom Alternatief toont wrapper-typen die worden gebruikt in generieke contexten zoals List<T>, of nieuwere Java-functies zoals Records.
| JSON-type | Voorbeeld | Java-type | Alternatief |
|---|---|---|---|
| string | "hello" | String | String |
| number (integer) | 42 | int | int / Integer |
| number (float) | 3.14 | double | double / Double |
| boolean | true | boolean | boolean / Boolean |
| null | null | Object | Object (or @Nullable String) |
| object | {"k": "v"} | NestedClass | Record (Java 16+) |
| array of strings | ["a", "b"] | List<String> | List<String> |
| array of objects | [{"id": 1}] | List<Item> | List<Item> |
| mixed array | [1, "a"] | List<Object> | List<Object> |
Java JSON-annotatieverwijzing
Bij het deserialiseren van JSON met Jackson of Gson bepalen annotaties hoe JSON-sleutels mappen naar Java-velden, hoe onbekende velden worden afgehandeld en hoe null-waarden worden behandeld. Deze verwijzing behandelt de annotaties die je het vaakst tegenkomt bij het werken met gegenereerde POJO's.
| Annotatie | Doel | Bibliotheek |
|---|---|---|
| @JsonProperty("name") | Maps a JSON key to a Java field with a different name | Jackson |
| @SerializedName("name") | Same as @JsonProperty, but for the Gson library | Gson |
| @JsonIgnoreProperties | Ignores unknown JSON keys during deserialization instead of failing | Jackson |
| @Nullable | Marks a field as accepting null values from JSON input | JSR 305 / JetBrains |
| @NotNull | Enforces that a field must not be null, throws on violation | Bean Validation |
| @JsonFormat(pattern=...) | Defines a date/time format for serialization and deserialization | Jackson |
POJO vs Record vs Lombok
Java heeft drie gangbare benaderingen voor het definiëren van getypeerde structuren om JSON-data in op te slaan. Elke benadering past bij een andere projectstijl en Java-versie. POJO's zijn het traditionele patroon met de breedste compatibiliteit. Records verminderen boilerplate voor onveranderlijke data. Lombok genereert getters, setters en constructors tijdens compilatie via annotaties.
Codevoorbeelden
Deze voorbeelden tonen hoe je gegenereerde Java POJO's gebruikt met Jackson voor deserialisatie, hoe je programmatisch Java-klassen produceert vanuit JavaScript en Python, en hoe je de jsonschema2pojo CLI-tool gebruikt voor batchgeneratie.
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
private int id;
private String name;
private String email;
private boolean active;
private double score;
private Address address;
private List<String> tags;
// getters and setters omitted for brevity
public static void main(String[] args) throws Exception {
String json = "{\"id\":1,\"name\":\"Alice\",\"email\":\"alice@example.com\",\"active\":true,\"score\":98.5,\"address\":{\"street\":\"123 Main St\",\"city\":\"Springfield\",\"zip\":\"12345\"},\"tags\":[\"admin\",\"user\"]}";
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json, User.class);
System.out.println(user.getName()); // -> Alice
}
}
class Address {
private String street;
private String city;
private String zip;
// getters and setters
}// Minimal JSON-to-Java-POJO generator in JS
function jsonToJava(obj, name = "Root") {
const classes = [];
function infer(val, fieldName) {
if (val === null) return "Object";
if (typeof val === "string") return "String";
if (typeof val === "number") return Number.isInteger(val) ? "int" : "double";
if (typeof val === "boolean") return "boolean";
if (Array.isArray(val)) {
const first = val.find(v => v !== null);
if (!first) return "List<Object>";
const elem = infer(first, fieldName);
const boxed = elem === "int" ? "Integer" : elem === "double" ? "Double" : elem === "boolean" ? "Boolean" : elem;
return `List<${boxed}>`;
}
if (typeof val === "object") {
const cls = fieldName.charAt(0).toUpperCase() + fieldName.slice(1);
build(val, cls);
return cls;
}
return "Object";
}
function build(obj, cls) {
const fields = Object.entries(obj).map(([k, v]) => {
const type = infer(v, k);
return ` private ${type} ${k};`;
});
classes.push(`public class ${cls} {\n${fields.join("\n")}\n}`);
}
build(obj, name);
return classes.join("\n\n");
}
console.log(jsonToJava({ id: 1, name: "Alice", scores: [98, 85] }, "User"));
// public class User {
// private int id;
// private String name;
// private List<Integer> scores;
// }import json
def json_to_java(obj: dict, class_name: str = "Root") -> str:
classes = []
def infer(val, name):
if val is None:
return "Object"
if isinstance(val, bool):
return "boolean"
if isinstance(val, int):
return "int"
if isinstance(val, float):
return "double"
if isinstance(val, str):
return "String"
if isinstance(val, list):
if not val:
return "List<Object>"
elem = infer(val[0], name)
boxed = {"int": "Integer", "double": "Double", "boolean": "Boolean"}.get(elem, elem)
return f"List<{boxed}>"
if isinstance(val, dict):
cls = name[0].upper() + name[1:]
build(val, cls)
return cls
return "Object"
def build(obj, cls):
fields = [f" private {infer(v, k)} {k};" for k, v in obj.items()]
classes.append(f"public class {cls} {{\n" + "\n".join(fields) + "\n}")
build(obj, class_name)
return "\n\n".join(classes)
data = json.loads('{"id": 1, "name": "Alice", "tags": ["admin"]}')
print(json_to_java(data, "User"))
# public class User {
# private int id;
# private String name;
# private List<String> tags;
# }# Install jsonschema2pojo (requires Java 8+)
# Download from https://github.com/joelittlejohn/jsonschema2pojo
# Generate POJOs from a JSON file
jsonschema2pojo --source user.json --target src/main/java \
--source-type json --annotation-style jackson2
# Generate with Gson annotations instead
jsonschema2pojo --source user.json --target src/main/java \
--source-type json --annotation-style gson
# From a JSON string via stdin
echo '{"id": 1, "name": "Alice", "tags": ["admin"]}' | \
jsonschema2pojo --source-type json --annotation-style jackson2 \
--target src/main/java --target-package com.example.model