Kotlin Deserialize Any Type Not Supported

Я пытаюсь десериализовать 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()
)

Размер продукта:

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 здесь


person Adrian Le Roy Devezin    schedule 24.10.2018    source источник
comment
Можете ли вы добавить класс данных для: ProductDimensions, ProductCategory, ProductImage и ProductAttribute   -  person Gomino    schedule 26.10.2018
comment
@Gomino добавил код   -  person Adrian Le Roy Devezin    schedule 26.10.2018
comment
Можете ли вы сказать мне, какую версию kotlin и kotlin.serialization вы используете?   -  person Gomino    schedule 30.10.2018
comment
@Gomino 1.3 сейчас   -  person Adrian Le Roy Devezin    schedule 30.10.2018


Ответы (2)


Вот рабочее решение cloud9 (просто запустите ./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

Хороший онлайн-инструмент для создания класса данных на основе необработанных данных json - это quicktype.io.

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

person Gomino    schedule 30.10.2018
comment
Как это сделать для MutableMap ‹String, String›? - person Rajesh Maurya; 07.11.2019

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

Была одна проблема в JSON в вашей ссылке pastebin, которая заключалась в том, что значение 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 требуется компилятор Kotlin 1.3.0 или выше.

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

person Yoni Gibbs    schedule 30.10.2018
comment
Ваш код выдает ошибку, это объявление является экспериментальным и должно быть помечено как '@ kotlinx.serialization.ImplicitReflectionSerializer' - person Adrian Le Roy Devezin; 30.10.2018
comment
Попробуйте вместо этого: val products = JSON(strictMode = false).parse(Product.serializer().list, File("./serializationTest.json").readText()) - person Yoni Gibbs; 30.10.2018