0
# Gson Serialization
1
2
Google Gson-based JSON serialization implementation for Ktor HTTP clients. Provides high-performance JSON processing with configurable Gson builder support for custom serialization behavior.
3
4
## Capabilities
5
6
### GsonSerializer Class
7
8
JsonSerializer implementation using Google's Gson library for JSON processing.
9
10
```kotlin { .api }
11
/**
12
* JsonSerializer using Gson as backend.
13
*/
14
@Deprecated("Please use ContentNegotiation plugin and its converters")
15
class GsonSerializer(block: GsonBuilder.() -> Unit = {}) : JsonSerializer {
16
private val backend: Gson
17
18
/**
19
* Convert data object to OutgoingContent using Gson serialization.
20
*/
21
override fun write(data: Any, contentType: ContentType): OutgoingContent
22
23
/**
24
* Read content from response using Gson deserialization.
25
*/
26
override fun read(type: TypeInfo, body: Input): Any
27
}
28
```
29
30
## Service Registration
31
32
The GsonSerializer is automatically discoverable on JVM through the ServiceLoader mechanism:
33
34
**META-INF/services/io.ktor.client.plugins.json.JsonSerializer**
35
```
36
io.ktor.client.plugins.gson.GsonSerializer
37
```
38
39
## Dependencies
40
41
To use GsonSerializer, add the Gson dependency to your project:
42
43
**Gradle**
44
```kotlin
45
implementation("io.ktor:ktor-client-gson:2.3.13")
46
```
47
48
**Maven**
49
```xml
50
<dependency>
51
<groupId>io.ktor</groupId>
52
<artifactId>ktor-client-gson-jvm</artifactId>
53
<version>2.3.13</version>
54
</dependency>
55
```
56
57
## Usage Examples
58
59
### Basic Usage
60
61
```kotlin
62
import io.ktor.client.*
63
import io.ktor.client.plugins.json.*
64
import io.ktor.client.plugins.gson.*
65
66
val client = HttpClient {
67
install(JsonPlugin) {
68
serializer = GsonSerializer()
69
}
70
}
71
```
72
73
### Custom Gson Configuration
74
75
```kotlin
76
val client = HttpClient {
77
install(JsonPlugin) {
78
serializer = GsonSerializer {
79
// Configure Gson builder
80
setPrettyPrinting()
81
setDateFormat("yyyy-MM-dd HH:mm:ss")
82
serializeNulls()
83
84
// Custom type adapters
85
registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeAdapter())
86
87
// Field naming strategy
88
setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
89
90
// Exclusion strategy
91
setExclusionStrategies(object : ExclusionStrategy {
92
override fun shouldSkipField(f: FieldAttributes): Boolean {
93
return f.getAnnotation(Exclude::class.java) != null
94
}
95
96
override fun shouldSkipClass(clazz: Class<*>): Boolean = false
97
})
98
}
99
}
100
}
101
```
102
103
### Data Classes with Gson
104
105
```kotlin
106
data class User(
107
val id: Long,
108
val name: String,
109
val email: String,
110
@SerializedName("created_at")
111
val createdAt: String
112
)
113
114
// POST request - automatic serialization
115
val response = client.post("https://api.example.com/users") {
116
contentType(ContentType.Application.Json)
117
setBody(User(0, "Alice", "alice@example.com", "2023-01-01"))
118
}
119
120
// GET request - automatic deserialization
121
val user: User = client.get("https://api.example.com/users/1").body()
122
```
123
124
### Complex Type Handling
125
126
```kotlin
127
// Custom type adapter for LocalDateTime
128
class LocalDateTimeAdapter : JsonSerializer<LocalDateTime>, JsonDeserializer<LocalDateTime> {
129
private val formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME
130
131
override fun serialize(
132
src: LocalDateTime,
133
typeOfSrc: Type,
134
context: JsonSerializationContext
135
): JsonElement {
136
return JsonPrimitive(src.format(formatter))
137
}
138
139
override fun deserialize(
140
json: JsonElement,
141
typeOfT: Type,
142
context: JsonDeserializationContext
143
): LocalDateTime {
144
return LocalDateTime.parse(json.asString, formatter)
145
}
146
}
147
148
// Usage with custom adapter
149
val client = HttpClient {
150
install(JsonPlugin) {
151
serializer = GsonSerializer {
152
registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeAdapter())
153
}
154
}
155
}
156
```
157
158
### Polymorphic Serialization
159
160
```kotlin
161
// Base class
162
abstract class Animal(val type: String)
163
164
// Implementations
165
data class Dog(val breed: String) : Animal("dog")
166
data class Cat(val color: String) : Animal("cat")
167
168
// Runtime type adapter
169
class AnimalTypeAdapter : RuntimeTypeAdapterFactory.of(Animal::class.java, "type")
170
.registerSubtype(Dog::class.java, "dog")
171
.registerSubtype(Cat::class.java, "cat")
172
173
val client = HttpClient {
174
install(JsonPlugin) {
175
serializer = GsonSerializer {
176
registerTypeAdapterFactory(AnimalTypeAdapter)
177
}
178
}
179
}
180
```
181
182
### Collection Handling
183
184
```kotlin
185
// Serializing collections
186
val users = listOf(
187
User(1, "Alice", "alice@example.com", "2023-01-01"),
188
User(2, "Bob", "bob@example.com", "2023-01-02")
189
)
190
191
val response = client.post("https://api.example.com/users/batch") {
192
contentType(ContentType.Application.Json)
193
setBody(users)
194
}
195
196
// Deserializing collections
197
val userList: List<User> = response.body()
198
```
199
200
### Error Handling
201
202
```kotlin
203
try {
204
val user: User = client.get("https://api.example.com/users/1").body()
205
} catch (e: JsonSyntaxException) {
206
// Malformed JSON
207
logger.error("Invalid JSON response", e)
208
} catch (e: JsonIOException) {
209
// IO error during parsing
210
logger.error("IO error reading JSON", e)
211
}
212
```
213
214
## Gson Configuration Options
215
216
The GsonSerializer supports all standard Gson configuration options:
217
218
- **Pretty Printing**: `setPrettyPrinting()`
219
- **Date Formatting**: `setDateFormat(pattern)`
220
- **Null Serialization**: `serializeNulls()`
221
- **Field Naming**: `setFieldNamingPolicy(policy)`
222
- **Type Adapters**: `registerTypeAdapter(type, adapter)`
223
- **Exclusion Strategies**: `setExclusionStrategies(strategy)`
224
- **Lenient Parsing**: `setLenient()`
225
- **HTML Escaping**: `disableHtmlEscaping()`
226
227
## Performance Considerations
228
229
- Gson instances are thread-safe and should be reused
230
- Type adapters are cached internally for better performance
231
- Consider using `@SerializedName` for field mapping instead of global naming policies
232
- Use exclusion strategies judiciously as they impact performance