I want to serialize nulls for a specific field or class.
In GSON, the option serializeNulls() applies to the whole JSON.
Example:
I took a few ideas from various answers here.
this implementation:
JsonNullable.isJsonNull() == trueJsonNullable.isJsonNull() == falseParent containing JsonNullable is nulldelegateAdapter by using a TypeAdapterFactoryobjects that may need to be serialized to null implement this interface
/**
* [JsonNullableTypeAdapterFactory] needs to be registered with the [com.google.gson.Gson]
* serializing implementations of [JsonNullable] for [JsonNullable] to work.
*
* [JsonNullable] allows objects to choose at runtime whether they should be serialized as "null"
* serialized normally, or be omitted from the JSON output from [com.google.gson.Gson].
*
* when [isJsonNull] returns true, the subclass will be serialized to a [com.google.gson.JsonNull].
*
* when [isJsonNull] returns false, the subclass will be serialized normally.
*/
interface JsonNullable {
/**
* return true to have the entire object serialized as `null` during JSON serialization.
* return false to have this object serialized normally.
*/
fun isJsonNull(): Boolean
}
type adapter factory that serializes values to null
class JsonNullableTypeAdapterFactory : TypeAdapterFactory {
override fun create(gson: Gson, type: TypeToken): TypeAdapter? {
return object : TypeAdapter() {
private val delegateAdapter = gson.getDelegateAdapter(this@JsonNullableTypeAdapterFactory, type)
override fun read(reader: JsonReader): T = delegateAdapter.read(reader)
override fun write(writer: JsonWriter, value: T?) {
if (value is JsonNullable && value.isJsonNull()) {
val originalSerializeNulls = writer.serializeNulls
writer.serializeNulls = true
writer.nullValue()
writer.serializeNulls = originalSerializeNulls
} else {
delegateAdapter.write(writer, value)
}
}
}
}
}
register thr type adapter factroy with GSON
new GsonBuilder()
// ....
.registerTypeAdapterFactory(new JsonNullableTypeAdapterFactory())
// ....
.create();
example object that gets serialized to JSON
data class Parent(
val hello: Child?,
val world: Child?
)
data class Child(
val name: String?
) : JsonNullable {
override fun isJsonNull(): Boolean = name == null
}