Gson serialize null for specific class or field

后端 未结 5 443
面向向阳花
面向向阳花 2021-01-01 11:00

I want to serialize nulls for a specific field or class.

In GSON, the option serializeNulls() applies to the whole JSON.

Example:



        
5条回答
  •  Happy的楠姐
    2021-01-01 11:53

    I took a few ideas from various answers here.

    this implementation:

    • lets you choose at runtime, whether the JSON is
      • null
        • happens when JsonNullable.isJsonNull() == true
      • not null
        • happens when JsonNullable.isJsonNull() == false
      • omitted from the JSON (useful for HTTP PATCH requests)
        • happens field in Parent containing JsonNullable is null
    • no annotations needed
    • properly delegates unhandled work to a delegateAdapter by using a TypeAdapterFactory

    objects 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
    }
    

提交回复
热议问题