【问题标题】:Retrofit 2.1.0 + Gson. Serialize @Body which is subclass改造 2.1.0 + Gson。序列化作为子类的@Body
【发布时间】:2016-11-21 13:05:41
【问题描述】:

Retrofit 有一个问题,它使用静态类型的类,而不是运行时类型来序列化它的 RequestBody。

假设我有两个班级:

class A{
   String a;
}

class B extends A{
   String b;
}

现在我想提出一个请求:

@Post("/someUrl)
Observable<Void> someRequest(@Body A body);

我想将 A 或 B 实例传递给 someRequest,并根据类类型正确序列化它们。

我尝试使用 RuntimeTypeAdapterFactory,它运行良好,但它在序列化后给了我额外的字段(类型字段)。 我的 A、B 类将只用于序列化。

【问题讨论】:

    标签: java android gson retrofit2


    【解决方案1】:

    考虑只重载方法本身:

    @Post("/someUrl)
    Observable<Void> someRequest(@Body A body);
    @Post("/someUrl)
    Observable<Void> someRequest(@Body B body);
    

    【讨论】:

    • 这是一个很好的答案,但我应该提到我只想有一种请求方法。
    【解决方案2】:

    我知道,这个问题很老,但真正正常的解决方案是在创建 Retrofit 实例时注册自定义类型适配器。示例here

    它也适用于 Kotlin 密封类:

    sealed class AbstractBody(val bodyType: String) {
    
        data class A(
            val someDataA: String
        ) : AbstractBody(bodyType = "A")
    
        data class B(
            val someDataB: String
        ) : AbstractBody(bodyType = "B")
    }
    

    在你的改造创造者中:

    private fun createRetrofit(baseUrl: String, okHttpClient: OkHttpClient) =
        Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(okHttpClient)
            .addConverterFactory(
                GsonConverterFactory.create(GsonBuilder().withCustomAdapters().create())
            )
            .build()
    
    private fun GsonBuilder.withCustomAdapters() = apply {
        registerTypeAdapter(
            AbstractBody::class.java,
            JsonSerializer<AbstractBody> { src, _, context ->
                when (src) {
                    is AbstractBody.A ->
                        context.serialize(src, AbstractBody.A::class.java)
                    is AbstractBody.B ->
                        context.serialize(src, AbstractBody.B::class.java)
                }
            }
        )
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-28
      • 2016-09-04
      • 1970-01-01
      • 2015-04-07
      相关资源
      最近更新 更多