العمل مع JSON في Kotlin: دليل شامل للتحليل والتسلسل
JSON (JavaScript Object Notation) لا يزال أحد أكثر تنسيقات تبادل البيانات شيوعًا في تطوير الويب الحديث. عند العمل مع Kotlin، سواء كان ذلك في جانب الخادم باستخدام Ktor أو تطبيق جوال لنظام Android، فإن القدرة على تحليل JSON وتسلسله بكفاءة هي مهارة أساسية. في هذه المقالة، سنستعرض ثلاثة أساليب رئيسية للعمل مع JSON في Kotlin: استخدام مكتبات Gson وMoshi والحل الرسمي من JetBrains وهو kotlinx.serialization.
لماذا يتطلب Kotlin نهجًا خاصًا مع JSON؟
Kotlin هي لغة مكتوبة بشكل ثابت مع ميزات مثل أمان القيم الخالية (null-safety)، وفئات البيانات (data classes)، والخصائص الافتراضية. يجب أن تأخذ مكتبات العمل مع JSON هذه الميزات في الاعتبار ليكون الكود ليس فقط فعالاً بل أيضًا سليمًا لغويًا (idiomatic). قد يؤدي الإعداد غير الصحيح إلى NullPointerException أو سلوك غير متوقع أثناء إلغاء التسلسل (deserialization).
1. استخدام Gson للعمل مع JSON
Gson من Google هي واحدة من أقدم وأكثر المكتبات انتشارًا. إنها بسيطة في الاستخدام ولكن لها بعض الخصائص عند العمل مع Kotlin.
إضافة التبعية (Dependency)
// build.gradle.ktsimplementation("com.google.code.gson:gson:2.10.1")تسلسل كائن إلى JSON
import com.google.gson.Gson
data class User( val id: Int, val name: String, val email: String? = null)
fun main() { val user = User(1, "إيفان بيتروف", "ivan@example.com") val gson = Gson() val json = gson.toJson(user) println(json) // الإخراج: {"id":1,"name":"إيفان بيتروف","email":"ivan@example.com"}}تحليل JSON إلى كائن
fun parseUser(jsonString: String): User { val gson = Gson() return gson.fromJson(jsonString, User::class.java)}
fun main() { val json = """{"id":2,"name":"آنا سميرنوفا","email":null}""" val user = parseUser(json) println(user.name) // آنا سميرنوفا}هام: يستخدم Gson تقنية الانعكاس (reflection) في Java وقد لا يراعي أمان القيم الخالية في Kotlin. أثناء إلغاء التسلسل، قد تحصل الحقول المُعلنة على أنها غير قابلة للصفر (non-null) على قيمة صفرية (null)، مما يؤدي إلى خطأ أثناء وقت التشغيل. يُوصى باستخدام @JvmOverloads والمنشئات ذات القيم الافتراضية.
2. Moshi — البديل الحديث من Square
تم إنشاء Moshi مع مراعاة خصائص Kotlin ويقدم تكاملًا أفضل مع أمان القيم الخالية وفئات البيانات.
إضافة التبعية
// build.gradle.ktsimplementation("com.squareup.moshi:moshi-kotlin:1.15.0")kapt("com.squareup.moshi:moshi-kotlin-codegen:1.15.0")مثال على العمل مع Moshi
import com.squareup.moshi.Moshiimport com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
data class Product( val id: Int, val title: String, val price: Double, val inStock: Boolean = false)
fun main() { val moshi = Moshi.Builder() .addLast(KotlinJsonAdapterFactory()) .build()
val adapter = moshi.adapter(Product::class.java)
// التسلسل val product = Product(101, "لابتوب", 89999.99, true) val json = adapter.toJson(product) println(json) // {"id":101,"title":"لابتوب","price":89999.99,"inStock":true}
// إلغاء التسلسل val jsonString = """{"id":102,"title":"فأرة","price":2500.00}""" val parsedProduct = adapter.fromJson(jsonString) println(parsedProduct?.title) // فأرة println(parsedProduct?.inStock) // false (القيمة الافتراضية)}يقوم Moshi بمعالجة القيم الافتراضية في فئات البيانات تلقائيًا ويعمل بشكل صحيح مع الأنواع القابلة للصفر (nullable types). للحصول على أداء أفضل، يُوصى باستخدام توليد الكود (code generation) عبر التعليمة @JsonClass.