Как разобрать полиморфные объекты в Котлине с помощью Моши - PullRequest
0 голосов
/ 24 сентября 2019

В настоящее время возникли проблемы с запечатанным классом PolymorphicJsonAdapterFactory и Kotlins.У меня есть API, который возвращает полиморфные домашние компоненты, и я пытаюсь проанализировать и создать полиморфный объект с помощью Moshi в Kotlin, но я получаю следующую ошибку:

  Caused by: java.lang.IllegalArgumentException: Cannot serialize abstract class home.HomeComponent
for class home.HomeComponent
for java.util.List<home.HomeComponent> components
for class home.HomeContent

Код:

sealed class HomeComponent(@Json(name = "_type") val type: HomeContentType) {

data class BannerComponent(@field:Json(name = "_id")
                               val id: String,
                               val image: String) : HomeComponent(HomeContentType.banner)

data class SpecialProductsComponent(@field:Json(name = "_id")
                                        val id: String,
                                        val style: List<Product>) : HomeComponent(HomeContentType.specialProducts)

data class CarouselBannerComponent(@field:Json(name = "_id")
                                       val id: String,
                                       val style: String,
                                       val images: List<String>) : HomeComponent(HomeContentType.carousel)
}

enum class HomeContentType {
    @Json(name = "banner")banner,
    @Json(name = "products")Products,
    @Json(name = "carousel")carousel
}

Класс ApiFetcher:


class HomeApiFetcher(private val backend: HomeContentBackend) : HomeFetcher {

    companion object {
        fun from(retrofit: Retrofit,
                 moshi: Moshi): HomeApiFetcher {

            val moshi = moshi.newBuilder()
                    .add(
                            PolymorphicJsonAdapterFactory.of(HomeComponent::class.java, "_type")
                                    .withSubtype(HomeComponent.BannerComponent::class.java, HomeContentType.banner.name)
                                    .withSubtype(HomeComponent.SpecialProductsComponent::class.java, HomeContentType.specialProducts.name)
                                    .withSubtype(HomeComponent.CarouselBannerComponent::class.java, HomeContentType.carousel.name))
                    .add(KotlinJsonAdapterFactory())
                    .build()

            val homeBackend = retrofit
                    .newBuilder()
                    .addConverterFactory(MoshiConverterFactory.create(moshi))
                    .build()
                    .create(HomeContentBackend::class.java)
            return HomeApiFetcher(homeBackend)
        }
    }

    override fun getHomeContent(): Single<HomeContent> {
        return backend.load()
    }
}

JSON от API:

{
    "common": {
        "background": "",
        "backgroundType": "NONE",
        "floatingImgs": {
            "left": "",
            "right": ""
        },
        "actualDate": "2019-09-23T15:03:20.8626882Z"
    },
    "components": [{
            "image": "http://image1.url",
            "_id": "carousel1",
            "style": "SLIDE",
            "_type": "banner"
        },
        {
            "products": [],
            "_id": "id1",
            "style": "CARD",
            "_type": "products"
        },
        {
            "images": ["http://image1.url",
                "http://image1.url",
                "http://image1.url"
            ],
            "_id": "carousel1",
            "style": "SLIDE",
            "_type": "carousel"
        }
    ]
}

Я не уверен, что не так в моем коде.Я получаю Cannot serialize abstract class HomeComponent ошибка

...