Gson — Google'ın Java nesnelerini JSON'a ve geri serileştirmek için kullandığı, Android geliştirmede yaygın olarak kullanılan bir kütüphanedir. Ayrıştırıcıları manuel olarak yazmadan karmaşık nesne grafiklerini kompakt JSON dizelerine dönüştürmeyi sağlar. Google Gson, 2024'e göre, kütüphanenin GitHub'da 23.000'den fazla yıldızı var ve Java ve Kotlin ekosisteminde JSON ile çalışmak için en popüler çözümlerden biri olmaya devam ediyor.
Önemli Noktalar
Gson, Google tarafından geliştirilen, nesneleri JSON gösterimine ve geri dönüştürmek için kullanılan bir Java kütüphanesidir. Sınıf yapılarını analiz etmek için yansıma kullanır, böylece ön yapılandırma olmadan çalışabilir. Gson, rastgele Java nesnelerini, koleksiyonları, dizileri, jenerikleri ve iç içe sınıfları destekler. Kütüphane temel kullanım için ek açıklama gerektirmez ancak ince ayar için bunları sağlar. Yansımanın ana dezavantajı, başlatma sırasında performans düşüşü ve derleme zamanında optimize edilememesidir; bu, yüzlerce modelin seri durumdan çıkarılması sırasında Android uygulamasının soğuk başlatılmasında özellikle belirgindir. Buna rağmen Gson, kararlılığı ve kapsamlı dokümantasyonu sayesinde çoğu proje için güvenilir bir seçim olmaya devam etmektedir.
Gson, Google tarafından 2008 yılında yayınlandı ve hızla Android uygulamalarında JSON için fiili standart haline geldi. Moshi ve kotlinx.serialization'ın ortaya çıkmasından önce Gson, Kotlin projeleri için tek popüler seçenekti. Entegrasyon kolaylığı — build.gradle'a tek bir bağımlılık eklemek — ve zorunlu ek açıklamaların olmaması, Gson'u her seviyedeki geliştirici arasında popüler hale getirdi.
// Gson'ı build.gradle'a ekleme
dependencies {
implementation 'com.google.code.gson:gson:2.10.1'
}
// Temel kullanım
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"}
Temel serileştirmeye ek olarak Gson, davranışı yapılandırmak için GsonBuilder sağlar: tarih biçimlendirme, HTML kaçışını devre dışı bırakma, anahtar büyük/küçük harf ve özel örnekler. GsonBuilder ayrıca kütüphanenin otomatik olarak işleyemediği türler için özel JsonSerializer ve JsonDeserializer kaydetmeye de olanak tanır. Yapılandırma esnekliği, GsonBuilder'ı modern Android geliştirmede kütüphaneyi belirli proje gereksinimlerine uyarlarken vazgeçilmez ve kullanışlı bir araç haline getirir.
toJson, yansıma yoluyla alanlarını analiz ederek bir Java nesnesini JSON dizesine dönüştürür. Varsayılan olarak Gson, transient ve static hariç tüm alanları dahil eder. Yöntem her türü destekler: ilkeller, nesneler, koleksiyonlar ve diziler. fromJson ters işlemi gerçekleştirir, bir JSON dizesini ve hedef nesne sınıfını kabul eder ve doldurulmuş alanlarla bir örnek döndürür.
Serileştirme sırasında Gson, iç içe alanlar dahil tüm nesne alanlarını yinelemeli olarak dolaşır. Döngüsel referanslar StackOverflowError'a yol açar, bu nedenle @Expose ek açıklaması veya özel bir bağdaştırıcı ile hariç tutulmaları gerekir. Koleksiyonlar için Gson, öğe türlerini korur, ancak jeneriklerle bir listeyi seri durumdan çıkarırken tür bilgisini korumak için TypeToken gerekir.
// İç içe nesne ile 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'a serileştirme
val json = gson.toJson(employee)
// JSON'dan seri durumdan çıkarma
val jsonString = """
{"id":2,"name":"Bob","address":{"city":"London","street":"Baker St"}}
"""
val parsed = gson.fromJson(jsonString, Employee::class.java)
Gson, serileştirme sürecini yönetmek için bir dizi ek açıklama sağlar. @SerializedName, alan adından farklı olan JSON anahtar adını belirtir. @Expose, bir alanın serileştirmeye dahil edilip edilmediğini kontrol eder: GsonBuilder.excludeFieldsWithoutExposeAnnotation() ile oluşturulan Gson yalnızca @Expose içeren alanları işler. @Since ve @Until, alan sürümlemesini kontrol eder.
@SerializedName ek açıklaması, ad uyuşmazlığı sorununu çözer: sunucu snake_case kullanırken kodda camelCase kullanılabilir. Ek açıklama, geriye dönük uyumluluk için bir değer ve isteğe bağlı alternatifler kabul eder. @Expose, hassas alanların (parolalar, tokenlar) @Expose(serialize = false) olarak işaretlenerek serileştirmeden gizlenmesine olanak tanır. Dahil etme ve hariç tutmanın yanı sıra, @Expose, GsonBuilder.excludeFieldsWithoutExposeAnnotation ile birleştirilerek bir alan beyaz listesi oluşturulabilir; bu, çok sayıda alanı olan nesneleri serileştirirken saldırı yüzeyini kontrol etmeye yardımcı olur.
// Gson ek açıklamalarıyla model
data class UserResponse(
@SerializedName("user_id")
val userId: Int,
@SerializedName("full_name",
alternate = [Alternative("name")])
val fullName: String,
@Expose(serialize = false)
val password: String
)
// @Expose filtreleme ile Gson
val gson = GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.setPrettyPrinting()
.create()
val user = UserResponse(1, "John", "secret123")
println(gson.toJson(user))
// {"user_id":1,"full_name":"John"} — parola hariç tutuldu
Jenerikler sorunu, Java ve Kotlin'de derleme zamanında tür silinmesidir. Gson, List<User>'ı seri durumdan çıkarırken öğe türünü bilmez ve List<Map<String, Any>> döndürür. Tür bilgisini korumak için Gson, TypeToken sağlar — anonim bir sınıf aracılığıyla tür parametresini yakalayan soyut bir sınıf. TypeToken olmadan, geliştiricinin her öğeyi Map'ten hedef türe manuel olarak dönüştürmesi gerekir, bu da hantal kod ve performans kaybına yol açar.
TypeToken, tür silme sorununu çözer. Geliştirici, gerekli tür parametresiyle TypeToken'ın anonim bir alt sınıfını oluşturur ve Gson, doğru seri durumdan çıkarma için sınıf imzasındaki bilgileri kullanır. TypeToken ayrıca Map, Set ve iç içe jenerikler dahil diğer parametreli türlerle de çalışır. Özellikle Map<String, List<User>> için tam iç içe tür imzasına sahip bir TypeToken gerekir, aksi takdirde Gson değerleri List<User> yerine List<Map<String, Any>> olarak seri durumdan çıkarır.
// Liste seri durumdan çıkarma için 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)
// Özel seri durumdan çıkarıcı
class LocalDateAdapter :
JsonDeserializer<LocalDate> {
override fun deserialize(
json: JsonElement,
typeOfT: java.lang.reflect.Type,
context: JsonDeserializationContext
): LocalDate {
return LocalDate.parse(json.asString)
}
}
Özel serileştirme mantığı için Gson, JsonSerializer ve JsonDeserializer arayüzlerini destekler. Bunlar GsonBuilder.registerTypeAdapter() aracılığıyla kaydedilir ve kütüphanenin otomatik olarak serileştiremediği türleri (Java 8 tarihleri, standart olmayan değerlere sahip Enum'lar veya kaynak koduna erişimi olmayan üçüncü taraf sınıfları) işlemeye olanak tanır. Bir bağdaştırıcı uygularken performansı izlemek önemlidir: özel bir bağdaştırıcı içinde yansıma çağırmak, manuel kontrolün avantajlarını ortadan kaldırır, bu nedenle doğrudan yöntem ve alan çağrıları tercih edilir. Gson ekosisteminde ayrıca UUID, Optional ve Joda-Time tarih çarkları gibi yaygın türler için bağdaştırıcılar sağlayan gson-extras modülü de bulunmaktadır.
GsonBuilder, serileştirmeyi ince ayarlamak için düzinelerce yöntem sağlar. setPrettyPrinting, okunabilirlik için çıktı JSON'una girinti ve satır sonları ekler. disableHtmlEscaping, dizelerde HTML karakter kaçışını devre dışı bırakır. setDateFormat, standart olmayan zaman gösterimleri kullanan sunucularla çalışırken kritik olan tarih biçimini belirtir. setLenient, bazı JSON biçimlendirme hatalarını yok sayan hoşgörülü ayrıştırma modunu etkinleştirir. addDeserializationExclusionStrategy, özel stratejilere dayalı olarak alanları programlı bir şekilde seri durumdan çıkarmanın dışında bırakmaya olanak tanır. Hata ayıklama için, setPrettyPrinting'in günlükle birleştirilmesi yararlıdır — JSON yanıtlarını günlüklerde okunabilir hale getirir ve uyuşmazlıkları bulmayı kolaylaştırır.
GsonBuilder'ın önemli bir özelliği, @Since ve @Until ek açıklamaları aracılığıyla alan sürümleme yönetimidir. Geliştirici, setVersion ile nesne sürümünü belirtir ve Gson, sürüm ek açıklamalarına göre alanları otomatik olarak dahil eder veya hariç tutar. Bu, aynı modelin sunucu protokolünün farklı sürümleri için kullanıldığı API evrimi sırasında kullanışlıdır. GsonBuilder ayrıca, aile türlerinin global işlenmesi için TypeAdapterFactory'nin ve karmaşık Map anahtarlarıyla doğru çalışma için complexMapKeySerialization'ın kaydedilmesini de destekler.
Sıkça Sorulan Sorular
Gson, Java nesnelerini JSON'a ve geri dönüştürmek için bir Google kütüphanesidir. Sunucu yanıtlarını ayrıştırmak, istekleri serileştirmek ve verileri yerel depolamada saklamak için Android uygulamalarında yaygın olarak kullanılır.
Varsayılan olarak Gson, serileştirme sırasında null alanları atlar. Null değerleri dahil etmek için GsonBuilder.serializeNulls() kullanın. Seri durumdan çıkarma sırasında JSON'da eksik olan alanlar null kalır veya tür için varsayılan değeri alır.
Moshi, Kotlin sınıfları için yansıma kullanmaz, bu da daha yüksek performans ve öngörülebilir davranış sağlar. Moshi ayrıca Kotlin null güvenliğini doğru şekilde işlerken Gson, null'ı null olmayan bir alana dönüştürerek istisnaya neden olabilir.
@SerializedName, adları eşleşmediğinde bir JSON anahtarını bir sınıf alanına bağlar. Örneğin, kotlinName alanı ve "kotlin_name" JSON anahtarı için @SerializedName("kotlin_name") ek açıklaması doğru dönüşümü sağlar.
TypeToken, anonim bir sınıf aracılığıyla tür parametresini yakalayan soyut bir sınıftır. Koleksiyonları ve diğer parametreli türleri seri durumdan çıkarmak için gereklidir, çünkü tür silme nedeniyle Gson, çalışma zamanında öğe türünü kurtaramaz.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun