我有改装的moshi,我想将动态内部数据对象发送到后端。
假设我需要在我的端点上修补一些数据:
@PATCH("/animals/{animalId}/attributes")
suspend fun updateAnimal(@Path("animalId") animalId: String, @Body request: MyPetsRequest)
但我的AnimalAttributes内在对象是动态的。
@JsonClass(generateAdapter = true)
@Parcelize
data class MyPetsRequest(
@Json(name = "name") val name: String,
@Json(name = "attributes") val attributes: AnimalAttributes
) : Parcelable
interface AnimalAttributes : Parcelable // or sealed class possible when share same base fields
@JsonClass(generateAdapter = true)
@Parcelize
data class DogAttributes(
@Json(name = "bark") val bark: Boolean,
@Json(name = "bite") val bite: Boolean,
) : AnimalAttributes
@JsonClass(generateAdapter = true)
@Parcelize
data class CatAttributes(
@Json(name = "weight") val weight: Int,
) : AnimalAttributes
我尝试为 Moshi 创建一个自定义适配器,但是当我使用@ToJson内部对象时,attributes数据被转义(所以完整的对象作为一个参数发送)。
class AnimalAttributesAdapter {
@ToJson
fun toJson(value: AnimalAttributes): String {
val moshi = Moshi.Builder().build()
return when (value) {
is DogAttributes -> moshi.adapter(DogAttributes::class.java).toJson(value)
is CatAttributes -> moshi.adapter(CatAttributes::class.java).toJson(value)
else -> throw UnsupportedOperationException("Unknown type to serialize object to json: $value")
}
}
/**
* Not supported, this object is used only one way to update data on server.
*/
@FromJson
fun fromJson(value: String): AnimalAttributes = throw UnsupportedOperationException()
}
Moshi.Builder().add(AnimalAttributesAdapter())
这种情况下的结果如下所示:
{"name":"my pet name","attributes":"{\"bark\":\"true\", \"bite\":\"false\"}"}
当我尝试使用PolymorphicJsonAdapterFactory它时,在属性之间添加了下一个参数,这对我的用例来说是不可接受的。
PolymorphicJsonAdapterFactory.of(AnimalAttributes::class.java, "animal")
.withSubtype(DogAttributes::class.java, "dog")
.withSubtype(CatAttributes::class.java, "cat")
结果在这种情况下添加了属性animal:{"name":"my pet name","attributes":{"animal":"dog","bark":true, "bite":false}}
我不需要将对象从 json 反序列化为数据类。我只需要创建一种对 json 的序列化方式。