'How to serialize an inner class as a single value with GSON
Assume the following two clases
class Person internal constructor(var name: String, var address: Address)
class Address internal constructor(var city: String, var postcode: String)
The JSON serialization of this is
{"name":"Bob","address":{"city":"London","postcode":"LO12 345"}}
On the API output, I want to serialise the address as a single string, and not an object. e.g. {"name":"Bob","address":"London, LO12 345"}
I can achieve this if I write a custom serializer for Person, and even managed to work around the issue of only changing this single attribute instead of everything. However, I still have the issue that I now need to change how every single class that uses Address.
I am wondering if instead, there is a way to writte a serializer for Address that would only return a value instead of an object, much like a primive does. Then I am hoping that every single class that uses Address, would behave as if Address was a String straight away and serialize it as such.
Is such a thing possible?
Solution 1:[1]
You can write a serialiser for Address like this:
class AddressSerialiser: JsonSerializer<Address> {
override fun serialize(p0: Address, p1: Type?, p2: JsonSerializationContext?) =
JsonPrimitive("${p0.city}, ${p0.postcode}")
}
This serialiser outputs a JsonPrimitive, which is a string containing the city and postcode.
You can then register this when creating a Gson:
val gson = GsonBuilder()
.registerTypeAdapter(Address::class.java, AddressSerialiser())
.create()
println(gson.toJson(Person("John", Address("Cambridge", "CB5 8HX"))))
Output:
{"name":"John","address":"Cambridge, CB5 8HX"}
Solution 2:[2]
Not exactly sure if this is what you're looking for but what if you simply make it a data class? Like
data class Address internal constructor(var city: String, var postcode: String)
Then the toString() of it is a very descriptive string, and similar objects also count as equal, like
val a = Address("London", "LO12 345")
val b = Address("London", "LO12 345")
println(a) //prints: Address(city=London, postcode=LO12 345)
println(a == b) //prints: true
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Sweeper |
| Solution 2 | Ivo Beckers |
