Kotlin десериализовать любой тип не поддерживается

Я пытаюсь десериализовать JSON в класс kotlin, используя kotlin.serialization. Однако, когда код идет для десериализации JSON, он выдает ошибку kotlinx.serialization.SerializationException: Any type is not supported

Может кто-нибудь помочь мне решить это?

Товар:

@Serializable
data class Product(
        val id: Int = 0,
        val name: String = "",
        val slug: String = "",
        val permalink: String = "",
        @SerialName("date_created") val dateCreated: String = "",
        @SerialName("date_created_gmt") val dateCreatedGmt: String = "",
        @SerialName("date_modified") val dateModified: String = "",
        @SerialName("date_modified_gmt") val dateModifiedGmt: String = "",
        val type: String = "",
        val status: String = "",
        val featured: Boolean = false,
        @SerialName("catalog_visibility") val catalogVisibility: String = "",
        val description: String = "",
        @SerialName("short_description") val shortDescription: String = "",
        val sku: String = "",
        val price: String = "",
        @SerialName("regular_price") val regularPrice: String = "",
        @SerialName("sale_price") val salePrice: String = "",
        @SerialName("on_sale") val onSale: Boolean = false,
        val purchasable: Boolean = false,
        @SerialName("total_sales") val totalSales: Int = 0,
        @SerialName("external_url") val externalUrl: String = "",
        @SerialName("tax_status") val taxStatus: String = "",
        @SerialName("tax_class") val taxClass: String = "",
        @SerialName("stock_quantity") val stockQuantity: String = "",
        @SerialName("stock_status") val stockStatus: String = "",
        val backorders: String = "",
        @SerialName("backorders_allowed") val backordersAllowed: Boolean = false,
        val backordered: Boolean = false,
        @SerialName("sold_individually") val soldIndividually: Boolean = false,
        val weight: String = "",
        val dimensions: ProductDimensions = ProductDimensions(),
        @SerialName("shipping_required") val shippingRequired: Boolean = false,
        @SerialName("shipping_taxable") val shippingTaxable: Boolean = false,
        @SerialName("shipping_class") val shippingClass: String = "",
        @SerialName("shipping_class_id") val shippingClassId: Int = 0,
        @SerialName("reviews_allowed") val reviewsAllowed: Boolean = false,
        @SerialName("average_rating") val averageRating: String = "",
        @SerialName("rating_count") val ratingCount: Int = 0,
        @SerialName("related_ids") val relatedIds: List<Int> = listOf(),
        @SerialName("upsell_ids") val upsellIds: List<Int> = listOf(),
        @SerialName("cross_sell_ids") val crossSellIds: List<Int> = listOf(),
        @SerialName("parent_id") val parentId: Int = 0,
        @SerialName("purchase_note") val purchaseNote: String = "",
        val categories: List<ProductCategory> = listOf(),
        val images: List<ProductImage> = listOf(),
        val attributes: List<ProductAttribute> = listOf(),
        val variations: List<Int> = listOf()
)

ProductDimension:

data class ProductDimensions(
        val length: String = "",
        val width: String = "",
        val height: String = ""
)

Атрибут продукта:

data class ProductAttribute(
        val id: Int = 0,
        val name: String = "",
        val position: Int = 0,
        val visible: Boolean = false,
        val variation: Boolean = false,
        val options: List<String> = listOf()
)

Категория продукта:

data class ProductCategory(
        val id: Int = 0,
        val name: String = "",
        val slug: String = ""
)

Изображение продукта:

data class ProductImage(
        val id: Int = 0,
        @SerialName("date_created") val dateCreated: String = "",
        @SerialName("date_created_gmt") val dateCreatedGmt: String = "",
        @SerialName("date_modified") val dateModified: String = "",
        @SerialName("date_modified_gmt") val dateModifiedGmt: String = "",
        val src: String = "",
        val name: String = "",
        val alt: String = ""
)

И связанный JSON находится на pastebin здесь

2 ответа

Решение

Вот рабочее облако9 (просто запустите ./gradlew run) решение с использованием последней версии Kotlin (1.3.0) и среды выполнения сериализации (0.9.0)

val serializer = Product.serializer().list
val json = JSON.nonstrict.parse<List<Product>>(serializer, jsonString)

Обратите внимание, что некоторые атрибуты должны иметь добавленную аннотацию @Optional для этой сериализации, чтобы работать с вашим образцом, следовательно, это не ограниченная версия синтаксического анализа.

@Serializable
data class Product(
        val id: Int = 0,
        val name: String = "",
        val slug: String = "",
        val permalink: String = "",
        @Optional @SerialName("date_created") val dateCreated: String = "",
        @SerialName("date_created_gmt") val dateCreatedGmt: String = "",
        @SerialName("date_modified") val dateModified: String = "",
        @SerialName("date_modified_gmt") val dateModifiedGmt: String = "",
        val type: String = "",
        val status: String = "",
        val featured: Boolean = false,
        @SerialName("catalog_visibility") val catalogVisibility: String = "",
        val description: String = "",
        @SerialName("short_description") val shortDescription: String = "",
        val sku: String = "",
        val price: String = "",
        @SerialName("regular_price") val regularPrice: String = "",
        @SerialName("sale_price") val salePrice: String = "",
        @SerialName("on_sale") val onSale: Boolean = false,
        val purchasable: Boolean = false,
        @SerialName("total_sales") val totalSales: Int = 0,
        @SerialName("external_url") val externalUrl: String = "",
        @SerialName("tax_status") val taxStatus: String = "",
        @SerialName("tax_class") val taxClass: String = "",
        @SerialName("stock_quantity") val stockQuantity: String = "",
        @Optional @SerialName("stock_status") val stockStatus: String = "",
        val backorders: String = "",
        @SerialName("backorders_allowed") val backordersAllowed: Boolean = false,
        val backordered: Boolean = false,
        @SerialName("sold_individually") val soldIndividually: Boolean = false,
        val weight: String = "",
        val dimensions: ProductDimensions = ProductDimensions(),
        @SerialName("shipping_required") val shippingRequired: Boolean = false,
        @SerialName("shipping_taxable") val shippingTaxable: Boolean = false,
        @SerialName("shipping_class") val shippingClass: String = "",
        @SerialName("shipping_class_id") val shippingClassId: Int = 0,
        @SerialName("reviews_allowed") val reviewsAllowed: Boolean = false,
        @SerialName("average_rating") val averageRating: String = "",
        @SerialName("rating_count") val ratingCount: Int = 0,
        @SerialName("related_ids") val relatedIds: List<Int> = listOf(),
        @SerialName("upsell_ids") val upsellIds: List<Int> = listOf(),
        @SerialName("cross_sell_ids") val crossSellIds: List<Int> = listOf(),
        @SerialName("parent_id") val parentId: Int = 0,
        @SerialName("purchase_note") val purchaseNote: String = "",

        val categories: List<ProductCategory> = listOf(),
        val images: List<ProductImage> = listOf(),
        val attributes: List<ProductAttribute> = listOf(),
        val variations: List<Int> = listOf()
)

Обратите внимание: date_created, stock_status

Quicktype.io - хороший онлайн-инструмент для генерации вашего класса данных на основе исходных данных json.

Изменить: Только что выяснил, что cloud9 был приобретен amazon два года назад, и вы больше не можете создать учетную запись, чтобы увидеть общедоступное рабочее пространство. Так вот ссылка на файловую систему

Я только что попробовал это и не мог повторить вашу проблему. Можете ли вы предоставить репозиторий Github, где мы можем увидеть проблему?

Была одна проблема в JSON в вашей ссылке, которая заключалась в том, что stock_status значение отсутствовало, поэтому я нажал эту ошибку: kotlinx.serialization.MissingFieldException: Field stock_status is required, but it was missing

Однако, как только я добавил это значение в JSON, я смог его десериализовать.

Вот код, который я использовал:

import kotlinx.serialization.*
import kotlinx.serialization.json.JSON
import java.io.File

val product = JSON(strictMode = false).parseList<Product>(File("./serializationTest.json").readText())

Другое дело, что согласно документации

Для использования Kotlin Serialization требуется компилятор Kotlin 1.3.0 или выше.

Kotlin 1.3 был официально выпущен совсем недавно, так что, возможно, вы используете кандидата на выпуск или что-то вроде этого вместо официального релиза (с которым он работал у меня)? Может быть, обновить все ваши зависимости до последних версий и попробовать еще раз?

Другие вопросы по тегам