ToolDeck

JSON به Java

تولید کلاس‌های Java POJO از JSON

یک مثال امتحان کنید
نام کلاس اصلی:

ورودی JSON

خروجی Java

به‌صورت محلی اجرا می‌شود · جای‌گذاری اسرار امن است
کلاس‌های Java اینجا نمایش داده می‌شوند…

تبدیل JSON به کلاس Java چیست؟

تبدیل JSON به کلاس Java یک شیء JSON خام را دریافت می‌کند و تعاریف Plain Old Java Object (POJO) با فیلدهای خصوصی، getter و setter تولید می‌کند. Java سیستم نوع داخلی برای JSON ندارد، بنابراین هر پاسخ API، فایل پیکربندی یا پیلود پیام JSON به یک کلاس متناظر نیاز دارد تا بتوانید به‌صورت ایمن از نظر نوع با آن کار کنید. کتابخانه‌هایی مانند Jackson و Gson از طریق reflection کلیدهای JSON را به فیلدهای Java نگاشت می‌کنند، اما ابتدا به وجود تعاریف کلاس نیاز دارند.

یک Java POJO استاندارد برای deserialize کردن JSON یک فیلد خصوصی برای هر کلید JSON، یک constructor بدون آرگومان، و یک جفت getter/setter به ازای هر فیلد تعریف می‌کند. اشیاء JSON تودرتو به کلاس‌های جداگانه تبدیل می‌شوند. آرایه‌ها به فیلدهای List<T> با import از java.util.List تبدیل می‌شوند. نوع‌های اولیه JSON به نوع‌های اولیه Java (int، double، boolean) یا نوع‌های wrapper آن‌ها (Integer، Double، Boolean) هنگام استفاده در generics نگاشت می‌شوند. مقادیر null معمولاً به Object یا یک نوع مرجع nullable نگاشت می‌شوند.

نوشتن این تعاریف کلاس به‌صورت دستی تکراری است. باید هر کلید JSON را بخوانید، نوع Java را از مقدار تشخیص دهید، قراردادهای نام‌گذاری از camelCase JSON به فیلدهای camelCase Java را اعمال کنید، نام‌های PascalCase برای اشیاء تودرتو بسازید، و boilerplate getter/setter اضافه کنید. برای یک شیء JSON با ۱۵ فیلد و ۳ شیء تودرتو، این یعنی نوشتن ۴ کلاس، بیش از ۳۰ متد، و حفظ یکپارچگی همه چیز. یک مبدل این کار را در چند میلی‌ثانیه انجام می‌دهد.

چرا از مبدل JSON به Java استفاده کنیم؟

ایجاد دستی Java POJO از JSON یعنی باید هر فیلد را بررسی کنید، نوع را از مقادیر نمونه تشخیص دهید، جفت‌های getter/setter بنویسید، و این فرایند را برای هر شیء تودرتو تکرار کنید. وقتی قرارداد API تغییر می‌کند، باید همه چیز را به‌صورت دستی به‌روزرسانی کنید. یک مبدل این کار مکانیکی را حذف می‌کند.

تولید فوری POJO
JSON را پیست کنید و تعاریف کامل کلاس‌های Java را در کمتر از یک ثانیه دریافت کنید. اشیاء تودرتو، لیست‌ها و نوع‌های اولیه به‌صورت خودکار تشخیص داده و نگاشت می‌شوند.
🔒
پردازش با اولویت حریم خصوصی
تبدیل کاملاً در مرورگر شما با استفاده از JavaScript اجرا می‌شود. داده JSON شما هرگز دستگاهتان را ترک نمی‌کند. کلیدهای API، توکن‌ها و داده‌های تولید خصوصی می‌مانند.
📝
تشخیص صحیح نوع
هر فیلد تولیدشده از نوع مناسب Java با توجه به مقدار JSON استفاده می‌کند: String، int، double، boolean، List<T>، یا Object برای null. نوع‌های wrapper در generics استفاده می‌شوند.
📦
بدون نصب یا ثبت‌نام
صفحه را باز کنید و JSON را پیست کنید. بدون JDK، بدون وابستگی‌های Maven، بدون حساب کاربری. روی هر دستگاهی با مرورگر کار می‌کند.

موارد استفاده JSON به Java

توسعه API با Spring Boot
DTO های درخواست و پاسخ را از نمونه‌های JSON API تولید کنید. شکل پیلود مورد انتظار را پیست کنید و کلاس‌های Java آماده برای annotation های @RequestBody و @ResponseBody در کنترلرهای Spring دریافت کنید.
توسعه اپلیکیشن Android
کلاس‌های مدل برای پاسخ‌های شبکه Retrofit یا Volley بسازید. JSON برگشتی از backend API خود را پیست کنید و POJO هایی سازگار با مبدل‌های Gson یا Moshi دریافت کنید.
یکپارچه‌سازی میکروسرویس
کلاس‌های پیام typed برای پیلودهای JSON در Kafka، RabbitMQ یا gRPC تعریف کنید. یک پیام نمونه را پیست کنید و POJO هایی تولید کنید که قرارداد مورد انتظار بین سرویس‌ها را مستند می‌کنند.
مهاجرت سیستم‌های قدیمی
پاسخ‌های JSON API را هنگام wrapping کردن REST endpoint ها در یک کلاینت typed به کلاس‌های Java تبدیل کنید. برای مهاجرت از الگوهای Map<String, Object> با نوع‌بندی ضعیف به مدل‌های دامنه مناسب مفید است.
اتوماسیون QA و تست
fixture های تست typed از نمونه‌های پاسخ API بسازید. مهندسان QA می‌توانند پاسخ‌های JSON واقعی را پیست کنند و تعاریف POJO برای استفاده در مجموعه‌های تست JUnit یا TestNG با assertion های AssertJ تولید کنند.
یادگیری الگوهای OOP در Java
دانشجویان می‌توانند هر ساختار JSON را پیست کنند و ببینند چگونه Java آن را با کلاس‌ها، فیلدها، getter، setter و نوع‌های تودرتو نمایش می‌دهد. خروجی مفهوم را ملموس می‌کند نه انتزاعی.

جدول نگاشت نوع JSON به Java

هر مقدار JSON به یک نوع Java خاص نگاشت می‌شود. جدول زیر نشان می‌دهد چگونه مبدل هر نوع JSON را به معادل Java ترجمه می‌کند. ستون Alternative نوع‌های wrapper مورد استفاده در زمینه‌های generic مانند List<T>، یا ویژگی‌های جدیدتر Java مانند Records را نشان می‌دهد.

نوع JSONمثالنوع Javaجایگزین
string"hello"StringString
number (integer)42intint / Integer
number (float)3.14doubledouble / Double
booleantruebooleanboolean / Boolean
nullnullObjectObject (or @Nullable String)
object{"k": "v"}NestedClassRecord (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>

مرجع annotation های JSON در Java

هنگام deserialize کردن JSON با Jackson یا Gson، annotation ها کنترل می‌کنند که کلیدهای JSON چگونه به فیلدهای Java نگاشت شوند، فیلدهای ناشناخته چگونه مدیریت شوند، و مقادیر null چگونه رفتار کنند. این مرجع annotation هایی را پوشش می‌دهد که هنگام کار با POJO های تولیدشده بیشتر با آن‌ها مواجه می‌شوید.

Annotationهدفکتابخانه
@JsonProperty("name")Maps a JSON key to a Java field with a different nameJackson
@SerializedName("name")Same as @JsonProperty, but for the Gson libraryGson
@JsonIgnorePropertiesIgnores unknown JSON keys during deserialization instead of failingJackson
@NullableMarks a field as accepting null values from JSON inputJSR 305 / JetBrains
@NotNullEnforces that a field must not be null, throws on violationBean Validation
@JsonFormat(pattern=...)Defines a date/time format for serialization and deserializationJackson

POJO در مقابل Record در مقابل Lombok

Java سه رویکرد رایج برای تعریف ساختارهای typed برای نگه‌داشتن داده JSON دارد. هر کدام با سبک پروژه و نسخه Java متفاوتی مناسب است. POJO الگوی سنتی با بیشترین سازگاری است. Record ها boilerplate را برای داده‌های immutable کاهش می‌دهند. Lombok در زمان کامپایل از طریق annotation ها getter، setter و constructor تولید می‌کند.

POJO
الگوی سنتی Java. با Java 8+ کار می‌کند. فیلدهای خصوصی به‌علاوه متدهای getter/setter تعریف می‌کنید. کنترل کامل بر mutability و منطق سفارشی. با هر کتابخانه JSON (Jackson، Gson، Moshi) سازگار است. انتخاب استاندارد برای Spring Boot، Android و پایگاه‌کدهای سازمانی.
Record (Java 16+)
از Java 16 به‌صورت داخلی (پیش‌نمایش در 14). سینتکس فشرده: record User(int id, String name) به‌طور خودکار constructor، accessor، equals، hashCode و toString تولید می‌کند. نمونه‌ها immutable هستند. Jackson از version 2.12 از record پشتیبانی می‌کند. برای value object ها و DTO هایی که به setter نیاز ندارید مناسب است.
Lombok @Data
annotation processor‌ ثرد-پارتی در زمان کامپایل. @Data getter، setter، equals، hashCode و toString تولید می‌کند. @Builder الگوی builder اضافه می‌کند. boilerplate را به سطح نزدیک به record کاهش می‌دهد در حالی که mutability را حفظ می‌کند. نیاز به افزودن Lombok به build tool (Maven/Gradle) و پلاگین IDE دارد.

نمونه کد

این مثال‌ها نشان می‌دهند چگونه Java POJO های تولیدشده را با Jackson برای deserialize کردن استفاده کنید، چگونه کلاس‌های Java را به‌صورت برنامه‌ای از JavaScript و Python تولید کنید، و چگونه از ابزار CLI جدید jsonschema2pojo برای تولید دسته‌ای استفاده کنید.

Java (Jackson deserialization)
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
}
JavaScript (generate Java POJO from JSON)
// 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;
// }
Python (generate Java classes from JSON)
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;
# }
CLI (jsonschema2pojo)
# 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

سوالات متداول

تفاوت بین POJO و Java Bean چیست؟
یک POJO (Plain Old Java Object) هر کلاس ساده Java بدون وابستگی به framework است. یک Java Bean یک POJO است که از قراردادهای خاصی پیروی می‌کند: یک constructor بدون آرگومان، فیلدهای خصوصی با getter و setter عمومی، و پیاده‌سازی Serializable. برای نگاشت JSON، اکثر کتابخانه‌ها به قراردادهای Bean (getter/setter) نیاز دارند اما Serializable را لازم ندارند. کلاس‌های تولیدشده توسط این ابزار از الگوی getter/setter مطابق با Bean پیروی می‌کنند.
با POJO های تولیدشده از کدام کتابخانه JSON استفاده کنم؟
Jackson (com.fasterxml.jackson) پرکاربردترین کتابخانه JSON در Java و پیش‌فرض در Spring Boot است. Gson (com.google.gson) در پروژه‌های Android محبوب است و API ساده‌تری دارد. Moshi یک جایگزین جدیدتر از Square است که برای تعامل با Kotlin طراحی شده. هر سه با POJO های استانداردی که getter و setter دارند کار می‌کنند.
مبدل چگونه اشیاء JSON تودرتو را مدیریت می‌کند؟
هر شیء تودرتو به یک کلاس Java جداگانه تبدیل می‌شود. اگر یک فیلد JSON به نام «address» حاوی یک شیء با کلیدهای «street» و «city» باشد، مبدل یک کلاس Address با آن فیلدها ایجاد می‌کند و فیلد والد را به‌عنوان نوع Address تعریف می‌کند. ساختارهای تودرتوی عمیق چندین تعریف کلاس تولید می‌کنند.
وقتی یک فیلد JSON مقدار null دارد چه اتفاقی می‌افتد؟
فیلدهای null به نوع Object تعریف می‌شوند زیرا مبدل نمی‌تواند نوع مورد نظر را تنها از یک مقدار null استنتاج کند. در عمل، باید Object را با نوع مورد انتظار (String، Integer و غیره) جایگزین کنید وقتی قرارداد API را می‌دانید. اگر از Jackson استفاده می‌کنید، مقادیر null به‌طور پیش‌فرض بدون خطا به فیلدهای نوع مرجع اختصاص داده می‌شوند.
آیا باید از Java Record به‌جای POJO برای JSON استفاده کنم؟
Record ها برای اشیاء انتقال داده immutable که به setter نیاز ندارید عملکرد خوبی دارند. Jackson از version 2.12 از record پشتیبانی می‌کند و Gson در نسخه‌های بعدی پشتیبانی را اضافه کرد. اگر پروژه شما روی Java 16+ اجرا می‌شود و پاسخ‌های API را به‌عنوان داده فقط‌خواندنی مدیریت می‌کنید، record ها boilerplate را کاهش می‌دهند. اگر به mutability نیاز دارید یا هدف Java 8 یا 11 است، با POJO بمانید.
چگونه کلیدهای JSON که شناسه معتبر Java نیستند را مدیریت کنم؟
کلیدهای JSON مانند «first-name» یا «2nd_place» نام فیلد معتبر Java نیستند. از @JsonProperty("first-name") در Jackson یا @SerializedName("first-name") در Gson برای نگاشت کلید JSON به نام فیلد معتبر Java مانند firstName استفاده کنید. مبدل به‌طور خودکار نام کلیدها را به فیلدهای camelCase Java تبدیل می‌کند.
آیا می‌توانم کلاس‌های Java را از JSON Schema به‌جای نمونه JSON تولید کنم؟
این ابزار کلاس‌ها را از نمونه‌های داده JSON تولید می‌کند. برای ورودی JSON Schema، از پروژه jsonschema2pojo (موجود به‌عنوان ابزار CLI، پلاگین Maven و پلاگین Gradle) استفاده کنید. یک فایل JSON Schema را می‌خواند و کلاس‌های Java با annotation، محدودیت‌های اعتبارسنجی، مقادیر پیش‌فرض و مستندات از توضیحات schema تولید می‌کند.