Gson — ما هي مكتبة JSON لجافا وكوتلن

المؤلف: IT Sectr نُشر: 2026-03-15 وقت القراءة: 8 دق

Gson — مكتبة من Google لتسلسل كائنات جافا إلى JSON والعكس، تُستخدم على نطاق واسع في تطوير Android. تتيح تحويل الرسوم البيانية المعقدة للكائنات إلى سلاسل JSON مضغوطة دون كتابة محللات يدويًا. وفقًا لـ Google Gson، 2024، تحتوي المكتبة على أكثر من 23 ألف نجمة على GitHub ولا تزال واحدة من أكثر الحلول شيوعًا للعمل مع JSON في نظام جافا وكوتلن البيئي.

الخلاصة

  • Gson — مكتبة Google لتسلسل JSON في جافا وكوتلن
  • fromJson — إلغاء تسلسل JSON إلى أي نوع كائن جافا
  • toJson — تسلسل كائن إلى سلسلة JSON
  • @SerializedName — تعليق توضيحي لربط مفتاح JSON بحقل الفئة
  • TypeToken — العمل مع الأنواع العامة والأنواع الم parametrized

ما هو Gson

Gson هي مكتبة جافا طورتها Google لتحويل الكائنات إلى تمثيل JSON والعكس. تستخدم الانعكاس لتحليل بنية الفئات، مما يسمح بالعمل دون تكوين مسبق. تدعم Gson كائنات جافا التعسفية، والمجموعات، والمصفوفات، والأنواع العامة، والفئات المتداخلة. لا تتطلب المكتبة تعليقات توضيحية للاستخدام الأساسي، لكنها توفرها للضبط الدقيق. العيب الرئيسي للانعكاس هو انخفاض الأداء أثناء التهيئة وعدم القدرة على التحسين في وقت الترجمة، وهو ملحوظ بشكل خاص عند بدء تشغيل تطبيق Android على البارد عند إلغاء تسلسل مئات النماذج. على الرغم من ذلك، تظل Gson خيارًا موثوقًا لمعظم المشاريع بفضل استقرارها وتوثيقها الشامل.

التاريخ والمكان في النظام البيئي

تم إصدار Gson بواسطة Google في عام 2008 وسرعان ما أصبح المعيار الفعلي لـ JSON في تطبيقات Android. قبل ظهور Moshi و kotlinx.serialization، كانت Gson هي الخيار الشائع الوحيد لمشاريع كوتلن. سهولة التكامل — إضافة تبعية واحدة إلى build.gradle — وغياب التعليقات التوضيحية الإلزامية جعل Gson شائعة بين المطورين من جميع المستويات.

groovy
// إضافة Gson في build.gradle
dependencies {
    implementation 'com.google.code.gson:gson:2.10.1'
}

// الاستخدام الأساسي
data class User(
    val id: Int,
    val name: String,
    val email: String
)

val gson = Gson()
val user = User(1, "John", "john@test.com")
val json = gson.toJson(user)
println(json) // {"id":1,"name":"John","email":"john@test.com"}

بالإضافة إلى التسلسل الأساسي، توفر Gson GsonBuilder لتكوين السلوك: تنسيق التواريخ، تعطيل هروب HTML، حالة المفاتيح والمثيلات المخصصة. يسمح GsonBuilder أيضًا بتسجيل JsonSerializer و JsonDeserializer مخصصين للأنواع التي لا تستطيع المكتبة معالجتها تلقائيًا. تجعل مرونة التكوين GsonBuilder أداة لا غنى عنها ومفيدة عند تكييف المكتبة مع متطلبات المشروع المحددة في تطوير Android الحديث.

العمليات الرئيسية toJson و fromJson

toJson يحول كائن جافا إلى سلسلة JSON عن طريق تحليل حقوله من خلال الانعكاس. افتراضيًا، يتضمن Gson جميع الحقول باستثناء transient و static. تدعم الطريقة أي أنواع: البدائية، والكائنات، والمجموعات، والمصفوفات. fromJson يقوم بالعملية العكسية، حيث يقبل سلسلة JSON وفئة الكائن الهدف، ويعيد مثيلًا مع الحقول المملوءة.

تحويل كائن إلى JSON

أثناء التسلسل، يجتاز Gson بشكل متكرر جميع حقول الكائن، بما في ذلك الحقول المتداخلة. المراجع الدائرية تؤدي إلى StackOverflowError، لذلك يجب استبعادها باستخدام التعليق التوضيحي @Expose أو محول مخصص. بالنسبة للمجموعات، يحافظ Gson على أنواع العناصر، ولكن عند إلغاء تسلسل قائمة بأنواع عامة، يلزم TypeToken للحفاظ على معلومات النوع.

kotlin
// data class مع كائن متداخل
data class Address(
    val city: String,
    val street: String
)

data class Employee(
    val id: Int,
    val name: String,
    val address: Address
)

val gson = Gson()
val employee = Employee(1, "Alice",
    Address("New York", "5th Ave"))

// التسلسل إلى JSON
val json = gson.toJson(employee)

// إلغاء التسلسل من JSON
val jsonString = """
{"id":2,"name":"Bob","address":{"city":"London","street":"Baker St"}}
"""
val parsed = gson.fromJson(jsonString, Employee::class.java)

التعليقات التوضيحية والتكوين

Gson توفر مجموعة من التعليقات التوضيحية لإدارة عملية التسلسل. @SerializedName يحدد اسم مفتاح JSON الذي يختلف عن اسم الحقل. @Expose يتحكم في تضمين الحقل في التسلسل: Gson الذي تم إنشاؤه عبر GsonBuilder.excludeFieldsWithoutExposeAnnotation() سيعالج فقط الحقول ذات @Expose. @Since و @Until يتحكمان في إصدارات الحقول.

@SerializedName و @Expose

التعليق التوضيحي @SerializedName يحل مشكلة عدم تطابق الأسماء: قد يستخدم الخادم snake_case بينما يستخدم الكود camelCase. يقبل التعليق التوضيحي قيمة وبدائل اختيارية للتوافق مع الإصدارات السابقة. @Expose يسمح بإخفاء الحقول الحساسة (كلمات المرور، الرموز) من التسلسل عن طريق وضع علامة عليها كـ @Expose(serialize = false). بالإضافة إلى التضمين والاستبعاد، يمكن دمج @Expose مع GsonBuilder.excludeFieldsWithoutExposeAnnotation لإنشاء قائمة بيضاء للحقول، مما يساعد في التحكم في سطح الهجوم عند تسلسل الكائنات ذات الحقول المتعددة.

kotlin
// نموذج مع تعليقات Gson التوضيحية
data class UserResponse(
    @SerializedName("user_id")
    val userId: Int,

    @SerializedName("full_name",
        alternate = [Alternative("name")])
    val fullName: String,

    @Expose(serialize = false)
    val password: String
)

// Gson مع تصفية @Expose
val gson = GsonBuilder()
    .excludeFieldsWithoutExposeAnnotation()
    .setPrettyPrinting()
    .create()

val user = UserResponse(1, "John", "secret123")
println(gson.toJson(user))
// {"user_id":1,"full_name":"John"} — تم استبعاد كلمة المرور

العمل مع الأنواع العامة

مشكلة الأنواع العامة في جافا وكوتلن هي محو الأنواع في وقت الترجمة. عندما يقوم Gson بإلغاء تسلسل List<User>، لا يعرف نوع العنصر ويعيد List<Map<String, Any>>. للحفاظ على معلومات النوع، يوفر Gson TypeToken — فئة مجردة تلتقط معامل النوع من خلال فئة مجهولة. بدون TypeToken، سيتعين على المطور تحويل كل عنصر يدويًا من Map إلى النوع الهدف، مما يؤدي إلى كود ضعيف وفقدان الأداء.

TypeToken للقوائم

TypeToken يحل مشكلة محو الأنواع. ينشئ المطور فئة فرعية مجهولة من TypeToken مع معامل النوع المطلوب، ويستخدم Gson المعلومات من توقيع الفئة لإلغاء التسلسل بشكل صحيح. يعمل TypeToken أيضًا مع Map و Set وأي أنواع أخرى م parametrized، بما في ذلك الأنواع العامة المتداخلة. على وجه الخصوص، بالنسبة لـ Map<String, List<User>>، يلزم TypeToken بتوقيع النوع المتداخل الكامل، وإلا فإن Gson يقوم بإلغاء تسلسل القيم كـ List<Map<String, Any>> بدلاً من List<User>.

kotlin
// TypeToken لإلغاء تسلسل القائمة
data class Product(
    val id: Int,
    val title: String,
    val price: Double
)

val jsonArray = """
[
    {"id":1,"title":"Phone","price":599.0},
    {"id":2,"title":"Laptop","price":1299.0}
]
"""

val gson = Gson()
val listType = object : TypeToken<List<Product>>() {}
val products: List<Product> =
    gson.fromJson(jsonArray, listType.type)

// مُلغٍ تسلسل مخصص
class LocalDateAdapter :
    JsonDeserializer<LocalDate> {

    override fun deserialize(
        json: JsonElement,
        typeOfT: java.lang.reflect.Type,
        context: JsonDeserializationContext
    ): LocalDate {
        return LocalDate.parse(json.asString)
    }
}

للمنطق المخصص للتسلسل، تدعم Gson واجهتي JsonSerializer و JsonDeserializer. يتم تسجيلهما عبر GsonBuilder.registerTypeAdapter() ويسمحان بمعالجة الأنواع التي لا تستطيع المكتبة تسلسلها تلقائيًا: تواريخ Java 8، Enum بقيم غير قياسية، أو فئات طرف ثالث بدون الوصول إلى الكود المصدري. عند تنفيذ محول، من المهم مراقبة الأداء: استدعاء الانعكاس داخل محول مخصص يلغي مزايا التحكم اليدوي، لذلك يفضل استخدام استدعاءات مباشرة للطرق والحقول. في نظام Gson البيئي، توجد أيضًا وحدة gson-extras التي توفر محولات للأنواع الشائعة مثل UUID و Optional وعجلات التاريخ Joda-Time.

التكوين عبر GsonBuilder

يوفر GsonBuilder عشرات الطرق للضبط الدقيق للتسلسل. setPrettyPrinting يضيف مسافات بادئة وفواصل أسطر إلى JSON الناتج لسهولة القراءة. disableHtmlEscaping يعطل هروب أحرف HTML في السلاسل. setDateFormat يحدد تنسيق التاريخ، وهو أمر بالغ الأهمية عند العمل مع خوادم تستخدم تمثيلات زمنية غير قياسية. setLenient يقوم بتمكين وضع التحليل المتساهل، الذي يتجاهل بعض أخطاء تنسيق JSON. addDeserializationExclusionStrategy يسمح باستبعاد الحقول برمجيًا من إلغاء التسلسل بناءً على استراتيجيات مخصصة. لتصحيح الأخطاء، من المفيد استخدام setPrettyPrinting مع التسجيل — فهو يجعل استجابات JSON قابلة للقراءة في السجلات ويبسط البحث عن التناقضات.

ميزة مهمة لـ GsonBuilder هي إدارة إصدارات الحقول من خلال التعليقات التوضيحية @Since و @Until. يحدد المطور إصدار الكائن عبر setVersion، ويقوم Gson تلقائيًا بتضمين أو استبعاد الحقول بناءً على تعليق الإصدار الخاص بها. هذا مفيد أثناء تطور API، عندما يتم استخدام نفس النموذج لإصدارات مختلفة من بروتوكول الخادم. يدعم GsonBuilder أيضًا تسجيل TypeAdapterFactory للمعالجة العالمية لأنواع العائلة و complexMapKeySerialization للعمل الصحيح مع مفاتيح Map المعقدة.

الأسئلة المتداولة

ما هو Gson في تطوير Android؟

Gson هي مكتبة Google لتحويل كائنات جافا إلى JSON والعكس. تُستخدم على نطاق واسع في تطبيقات Android لتحليل استجابات الخادم، وتسلسل الطلبات، وتخزين البيانات في التخزين المحلي.

كيف يتعامل Gson مع القيم الفارغة (null)؟

افتراضيًا، يتخطى Gson الحقول الفارغة أثناء التسلسل. لتضمين القيم الفارغة، استخدم GsonBuilder.serializeNulls(). أثناء إلغاء التسلسل، تظل الحقول المفقودة في JSON فارغة أو تأخذ القيمة الافتراضية للنوع.

ما الفرق بين Gson و Moshi؟

Moshi لا يستخدم الانعكاس لفئات كوتلن، مما يوفر أداءً أعلى وسلوكًا يمكن التنبؤ به. يتعامل Moshi أيضًا بشكل صحيح مع سلامة القيم الفارغة في كوتلن، بينما قد يقوم Gson بإلغاء تسلسل null إلى حقل غير فارغ، مما يسبب استثناءً.

كيف يعمل @SerializedName في Gson؟

@SerializedName يربط مفتاح JSON بحقل الفئة عندما لا تتطابق أسماؤهما. على سبيل المثال، للحقل kotlinName ومفتاح JSON "kotlin_name"، يضمن التعليق التوضيحي @SerializedName("kotlin_name") التحويل الصحيح.

ما هو TypeToken في Gson؟

TypeToken هو فئة مجردة تلتقط معامل النوع من خلال فئة مجهولة. إنه ضروري لإلغاء تسلسل المجموعات والأنواع الم parametrized الأخرى، لأنه بسبب محو الأنواع، لا يمكن لـ Gson استعادة نوع العنصر في وقت التشغيل.

الملخص

  • Gson — مكتبة Google لتسلسل JSON مع دعم جافا وكوتلن
  • toJson و fromJson — الطرق الرئيسية لتسلسل وإلغاء تسلسل الكائنات
  • @SerializedName — تعليق توضيحي لربط الحقول بمفاتيح JSON عندما لا تتطابق الأسماء
  • @Expose — التحكم في رؤية الحقول أثناء التسلسل عبر GsonBuilder
  • TypeToken — حل مشكلة محو الأنواع للمجموعات الم parametrized
  • GsonBuilder — تكوين التنسيق والإصدارات والتواريخ والمحولات المخصصة
  • JsonSerializer/JsonDeserializer — واجهات لمعالجة الأنواع ذات المنطق غير القياسي

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا