JSON to Java
Buat kelas Java POJO dari JSON
Input JSON
Output Java
Apa itu Konversi JSON ke Kelas Java?
Konversi JSON ke kelas Java mengambil objek JSON mentah dan menghasilkan definisi Plain Old Java Object (POJO) dengan field private, getter, dan setter. Java tidak memiliki sistem tipe JSON bawaan, sehingga setiap respons API JSON, file konfigurasi, atau payload pesan memerlukan class yang sesuai sebelum Anda dapat menggunakannya secara type-safe. Library seperti Jackson dan Gson memetakan kunci JSON ke field Java melalui reflection, tetapi mereka memerlukan definisi class yang sudah ada terlebih dahulu.
Sebuah Java POJO standar untuk deserialisasi JSON mendeklarasikan field private untuk setiap kunci JSON, konstruktor tanpa argumen, dan pasangan getter/setter per field. Objek JSON bersarang menjadi class terpisah. Array menjadi field List<T> dengan impor java.util.List. Tipe JSON primitif dipetakan ke tipe primitif Java (int, double, boolean) atau tipe wrapper-nya (Integer, Double, Boolean) saat digunakan di dalam generik. Nilai null biasanya dipetakan ke Object atau tipe referensi nullable.
Menulis definisi class ini secara manual adalah pekerjaan yang berulang. Anda membaca setiap kunci JSON, menentukan tipe Java dari nilainya, mengonversi konvensi penamaan dari camelCase JSON ke field Java camelCase, membuat nama class PascalCase untuk objek bersarang, dan menambahkan boilerplate getter/setter. Untuk objek JSON dengan 15 field dan 3 objek bersarang, itu berarti menulis 4 class, 30+ metode, dan menjaga semuanya tetap konsisten. Sebuah konverter melakukan ini dalam hitungan milidetik.
Mengapa Menggunakan Konverter JSON ke Java?
Membuat Java POJO dari JSON secara manual berarti memeriksa setiap field, menyimpulkan tipe dari nilai sampel, menulis pasangan getter/setter, dan mengulangi proses untuk setiap objek bersarang. Ketika kontrak API berubah, Anda memperbarui semuanya secara manual. Sebuah konverter menghilangkan pekerjaan mekanis tersebut.
Kasus Penggunaan JSON ke Java
Pemetaan Tipe JSON ke Java
Setiap nilai JSON dipetakan ke tipe Java yang spesifik. Tabel di bawah menunjukkan cara konverter menerjemahkan setiap tipe JSON ke padanannya di Java. Kolom Alternatif menampilkan tipe wrapper yang digunakan dalam konteks generik seperti List<T>, atau fitur Java yang lebih baru seperti Records.
| Tipe JSON | Contoh | Tipe Java | Alternatif |
|---|---|---|---|
| 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> |
Referensi Anotasi JSON Java
Saat melakukan deserialisasi JSON dengan Jackson atau Gson, anotasi mengontrol cara kunci JSON dipetakan ke field Java, cara field yang tidak dikenal ditangani, dan cara nilai null diperlakukan. Referensi ini mencakup anotasi yang paling sering Anda temui saat bekerja dengan POJO yang dihasilkan.
| Anotasi | Tujuan | Library |
|---|---|---|
| @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 memiliki tiga pendekatan umum untuk mendefinisikan struktur bertipe guna menyimpan data JSON. Masing-masing cocok untuk gaya proyek dan versi Java yang berbeda. POJO adalah pola tradisional dengan kompatibilitas terluas. Record mengurangi boilerplate untuk data yang tidak dapat diubah. Lombok menghasilkan getter, setter, dan konstruktor pada waktu kompilasi melalui anotasi.
Contoh Kode
Contoh-contoh ini menunjukkan cara menggunakan Java POJO yang dihasilkan dengan Jackson untuk deserialisasi, cara membuat kelas Java secara programatik dari JavaScript dan Python, dan cara menggunakan alat CLI jsonschema2pojo untuk pembuatan massal.
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