Gson — de bibliotheek van Google voor serialisatie van Java-objecten naar JSON en terug, veel gebruikt in Android-ontwikkeling. Het maakt conversie van complexe objectgrafen naar compacte JSON-strings mogelijk zonder handmatig parsers te schrijven. Volgens Google Gson, 2024, heeft de bibliotheek meer dan 23 duizend sterren op GitHub en blijft het een van de populairste oplossingen voor het werken met JSON in het Java- en Kotlin-ecosysteem.
Belangrijkste punten
Gson — is een Java-bibliotheek ontwikkeld door Google voor het converteren van objecten naar JSON-weergave en terug. Het gebruikt reflectie om de structuur van klassen te analyseren, waardoor werken zonder voorafgaande configuratie mogelijk is. Gson ondersteunt willekeurige Java-objecten, collecties, arrays, generics en geneste klassen. De bibliotheek vereist geen annotaties voor basisgebruik, maar biedt ze wel voor fijnafstemming. Het grootste nadeel van reflectie is de verminderde prestaties bij initialisatie en het onvermogen om te optimaliseren tijdens compilatie, wat vooral merkbaar is bij een koude start van een Android-app bij het deserialiseren van honderden modellen. Desondanks blijft Gson een betrouwbare keuze voor de meeste projecten dankzij stabiliteit en uitgebreide documentatie.
Gson werd in 2008 door Google uitgebracht en werd snel de de facto standaard voor JSON in Android-applicaties. Vóór de komst van Moshi en kotlinx.serialization bleef Gson de enige populaire keuze voor Kotlin-projecten. Eenvoudige integratie — het toevoegen van één afhankelijkheid in build.gradle — en het ontbreken van verplichte annotaties maakten Gson populair onder ontwikkelaars van elk niveau.
// Gson toevoegen in build.gradle
dependencies {
implementation 'com.google.code.gson:gson:2.10.1'
}
// Basisgebruik
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"}
Naast basisserialisatie biedt Gson GsonBuilder voor het configureren van gedrag: datumnotatie, uitschakelen van HTML-escapes, sleutelregister en aangepaste instanties. GsonBuilder maakt het ook mogelijk om aangepaste JsonSerializer en JsonDeserializer te registreren voor typen die de bibliotheek niet automatisch kan verwerken. De flexibiliteit van configuratie maakt GsonBuilder een onmisbaar en nuttig hulpmiddel bij het aanpassen van de bibliotheek aan specifieke projectvereisten in moderne Android-ontwikkeling.
toJson converteert een Java-object naar een JSON-string door de velden via reflectie te analyseren. Standaard neemt Gson alle velden op, behalve transient en static. De methode ondersteunt alle typen: primitieven, objecten, collecties en arrays. fromJson voert de omgekeerde conversie uit, ontvangt een JSON-string en de klasse van het doelobject, en retourneert een instantie met ingevulde velden.
Tijdens serialisatie doorloopt Gson recursief alle velden van het object, inclusief geneste velden. Cyclische verwijzingen leiden tot StackOverflowError, dus deze moeten worden uitgesloten via de @Expose-annotatie of een aangepaste adapter. Voor collecties behoudt Gson het type elementen, maar bij deserialisatie van een lijst met generics is TypeToken nodig om type-informatie te behouden.
// data class met genest object
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"))
// Serialisatie naar JSON
val json = gson.toJson(employee)
// Deserialisatie uit JSON
val jsonString = """
{"id":2,"name":"Bob","address":{"city":"London","street":"Baker St"}}
"""
val parsed = gson.fromJson(jsonString, Employee::class.java)
Gson biedt een set annotaties voor het beheren van het serialisatieproces. @SerializedName specificeert de naam van de JSON-sleutel die verschilt van de veldnaam. @Expose beheert het opnemen van het veld in serialisatie: Gson gemaakt via GsonBuilder.excludeFieldsWithoutExposeAnnotation() verwerkt alleen velden met @Expose. @Since en @Until beheren versiebeheer van velden.
De @SerializedName-annotatie lost het probleem van naamgevingsverschillen op: de server kan snake_case gebruiken, terwijl in de code camelCase wordt gebruikt. De annotatie accepteert een waarde en optionele alternatieven voor achterwaartse compatibiliteit. @Expose maakt het mogelijk gevoelige velden (wachtwoorden, tokens) te verbergen voor serialisatie door ze te markeren als @Expose(serialize = false). Naast opnemen en uitsluiten, kan @Expose worden gecombineerd met GsonBuilder.excludeFieldsWithoutExposeAnnotation om een witte lijst van velden te maken, wat helpt het aanvalsoppervlak te beheersen bij serialisatie van objecten met veel velden.
// Model met Gson-annotaties
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 met @Expose-filter
val gson = GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.setPrettyPrinting()
.create()
val user = UserResponse(1, "John", "secret123")
println(gson.toJson(user))
// {"user_id":1,"full_name":"John"} — password excluded
Het probleem van generics in Java en Kotlin ligt in het wissen van types tijdens compilatie. Wanneer Gson List<User> deserialiseert, kent het het type element niet en retourneert het List<Map<String, Any>>. Om type-informatie te behouden, biedt Gson TypeToken — een abstracte klasse die de typeparameter vastlegt via een anonieme klasse. Zonder TypeToken zou de ontwikkelaar elk element handmatig van Map naar het doeltype moeten converteren, wat leidt tot omslachtige code en prestatieverlies.
TypeToken lost het probleem van typewissing op. De ontwikkelaar maakt een anonieme afstammeling van TypeToken met de vereiste typeparameter, en Gson gebruikt de informatie uit de klassensignatuur voor correcte deserialisatie. TypeToken werkt ook met Map, Set en alle andere geparametriseerde typen, inclusief geneste generics. In het bijzonder is voor Map<String, List<User>> een TypeToken met de volledige handtekening van het geneste type vereist, anders deserialiseert Gson de waarden als List<Map<String, Any>> in plaats van List<User>.
// TypeToken voor deserialisatie van lijst
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)
// Aangepaste deserialisator
class LocalDateAdapter :
JsonDeserializer<LocalDate> {
override fun deserialize(
json: JsonElement,
typeOfT: java.lang.reflect.Type,
context: JsonDeserializationContext
): LocalDate {
return LocalDate.parse(json.asString)
}
}
Voor aangepaste serialisatielogica ondersteunt Gson de interfaces JsonSerializer en JsonDeserializer. Ze worden geregistreerd via GsonBuilder.registerTypeAdapter() en maken het mogelijk typen te verwerken die de bibliotheek niet automatisch kan serialiseren: Java 8-datums, Enum met niet-standaardwaarden of klassen van derden zonder toegang tot de broncode. Bij het implementeren van een adapter is het belangrijk om prestaties te bewaken: het aanroepen van reflectie binnen een aangepaste adapter maakt de voordelen van handmatig beheer teniet, dus de voorkeur gaat uit naar directe methode- en veldaanroepen. In het Gson-ecosysteem bestaat ook de module gson-extras die adapters biedt voor veelvoorkomende typen zoals UUID, Optional en Joda-Time-datumtypen.
GsonBuilder biedt tientallen methoden voor fijnafstemming van serialisatie. setPrettyPrinting voegt inspringing en nieuwe regels toe aan de uitvoer-JSON voor leesbaarheid. disableHtmlEscaping schakelt het escapen van HTML-tekens in strings uit. setDateFormat stelt de datumnotatie in, wat kritisch is bij het werken met servers die niet-standaard tijdweergaven gebruiken. setLenient activeert een soepele parsermodus die sommige JSON-opmaakfouten negeert. addDeserializationExclusionStrategy maakt programmatische uitsluiting van velden uit deserialisatie mogelijk op basis van aangepaste strategieën. Voor debugging is de methode setPrettyPrinting nuttig in combinatie met logging — het maakt JSON-reacties leesbaar in logs en vereenvoudigt het vinden van inconsistenties.
Een belangrijke mogelijkheid van GsonBuilder is het beheren van veldversiebeheer via de @Since- en @Until-annotaties. De ontwikkelaar specificeert de objectversie via setVersion, en Gson neemt automatisch velden op of sluit ze uit op basis van hun versieannotatie. Dit is nuttig bij API-evolutie, wanneer hetzelfde model wordt gebruikt voor verschillende versies van het serverprotocol. GsonBuilder ondersteunt ook registratie van TypeAdapterFactory voor globale verwerking van typefamilies en complexMapKeySerialization voor correct werken met complexe Map-sleutels.
Veelgestelde vragen
Gson — is een Google-bibliotheek voor het converteren van Java-objecten naar JSON en terug. Het wordt veel gebruikt in Android-apps voor het parsen van serverantwoorden, serialiseren van verzoeken en opslaan van gegevens in lokale opslag.
Standaard slaat Gson velden met null over bij serialisatie. Gebruik GsonBuilder.serializeNulls() om null-waarden in te schakelen. Bij deserialisatie blijven ontbrekende velden in JSON null of krijgen ze de standaardwaarde voor het type.
Moshi gebruikt geen reflectie voor Kotlin-klassen, wat zorgt voor betere prestaties en voorspelbaar gedrag. Moshi verwerkt ook correct de null-veiligheid van Kotlin, terwijl Gson null kan deserialiseren naar een non-null veld, wat een uitzondering veroorzaakt.
@SerializedName koppelt een JSON-sleutel aan een klasseveld wanneer hun namen niet overeenkomen. Bijvoorbeeld, voor het veld kotlinName en de JSON-sleutel „kotlin_name” zorgt de annotatie @SerializedName(„kotlin_name”) voor correcte conversie.
TypeToken — is een abstracte klasse die de typeparameter vastlegt via een anonieme klasse. Het is nodig voor deserialisatie van collecties en andere geparametriseerde typen, omdat Gson door typewissing het type element niet kan herstellen tijdens uitvoering.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook