#android #kotlin #retrofit2 #moshi
Вопрос:
У меня есть 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}}
I don’t need to deserialize object from json to data class. I only need create one way serialization to json.