微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我该如何使用Kotlin的序列化库反序列化对象列表?

如何解决我该如何使用Kotlin的序列化库反序列化对象列表?

我在运行时遇到了以下异常,调试器尝试使用Kotlinx.Serialization库尝试从我的Kotlin Android食谱应用程序的Algolia索引中反序列化数据。该应用程序可以编译并正常运行,但是UI上没有显示结果。

kotlinx.serialization.json.JsonDecodingException: Unexpected JSON token at offset -1: Failed to parse 'int'.
 JSON input: {"amount":1.5,"name":"green beans","original":"1.5 pounds of green beans","unit":"pounds","unitLong":"pounds","unitShort":"lbs"}

现在从外观上看,出现了这个异常,反序列化器似乎很困惑,试图对我的 Ingredients 数据类进行反序列化。我将如何对其进行反序列化?。

正在发送的示例JSON数据。

{
  "cuisine": "European","diet": "vegetarian","difficulty": 2,"dishType": "Dinner","duration": 30,"durationUnit": "minutes","image": "https://c.recipeland.com/images/r/1396/12f9fc271d8f1bfac5f6_550.jpg","ingredients": [
    {
      "amount": 1.5,"name": "green beans","original": "1.5 pounds of green beans","unit": "pounds","unitLong": "pounds","unitShort": "lbs"
    },{
      "amount": 1,"name": "onion","original": "1.5 medium onion","unit": "medium","unitLong": "medium","unitShort": "med"
    },{
      "amount": 2,"name": "garlic","original": "2 teaspoons of garlic","unit": "teaspoons","unitLong": "teaspoons","unitShort": "tsps"
    },"name": "olive oil","original": "1 teaspoon olive oil","unit": "teaspoon","unitLong": "teaspoon","name": "mushrooms","original": "1 cup mushrooms","unit": "cup","unitLong": "cup","unitShort": "cup"
    },"name": "cherry tomatoes","original": "1 cup cherry tomatoes","unitShort": "cup"
    }
  ],"name": "Green Beans with Mushrooms and Cherry Tomatoes","preparation": [
    "Steam green beans until tender.","Drain and set aside. Sauté onion and garlic in a medium skillet coated with olive oil,until tender. About 2 to 3 minutes.","Add mushrooms and sauté until tender. Stir in green beans and tomotoes until heated."
  ],"yield": 4,"objectID": "0"
}

我为配方设置了以下数据类:

Recipe.kt

@IgnoreExtraProperties
@Serializable
data class Recipe(
    var difficulty: Int = 0,var dishType: String? = null,var duration: Int = 0,var durationUnit: String? = null,var image: String? = null,var diet: String? = null,var cuisine: String? = null,var name: String? = null,var ingredients: List<Ingredient> = emptyList(),var preparation: List<String> = emptyList(),var yield: Int = 0
    ) {

Ingredient.kt

@Serializable
data class Ingredient(
    var amount: Int = 0,var original: String? = null,// Original text of the ingredient
    var unit: String? = null,var unitLong: String? = null,var unitShort: String? = null
)

我从Algolia的InstantSearch Android入门指南中获得了这段代码,该代码反序列化了索引中的数据。

    private val datasourceFactory = SearcherSingleIndexDataSource.Factory(searcher) { hit ->
        hit.deserialize(Recipe.serializer()) // Problem line I assume
    }

    val pagedListConfig = PagedList.Config.Builder().setPageSize(50).build()
    val recipes: LiveData<PagedList<Recipe>> =
        LivePagedListBuilder(datasourceFactory,pagedListConfig).build()
    val searchBox =
        SearchBoxConnectorPagedList(searcher,listof(recipes))

我尝试使用以下代码手动创建对象,但是在尝试创建成分列表时遇到问题。

    val dataSourceFactory = SearcherSingleIndexDataSource.Factory(searcher) { hit ->
        Recipe(
            hit.json.getPrimitive("difficulty").content.toInt(),hit.json.getPrimitive("dishType").content,hit.json.getPrimitive("duration").content.toInt(),hit.json.getPrimitive("durationUnit").content,hit.json.getPrimitive("image").content,hit.json.getPrimitive("diet").content,hit.json.getPrimitive("cuisine").content,hit.json.getPrimitive("name").content,listof(
                Ingredient(
                    hit.json.getPrimitive("amount").content.toInt(),hit.json.getPrimitive("original").content,hit.json.getPrimitive("unit").content,hit.json.getPrimitive("unitLong").content,hit.json.getPrimitive("unitShort").content
                )
            ),hit.json.getArray("preparation").content.map { prep -> prep.content },hit.json.getPrimitive("yield").content.toInt()
        )
    }

我不确定我是否正确地正确创建了 preparation 属性成员,以及整个创建配料表的过程是否使我感到困惑。任何帮助将不胜感激,对于我的第一篇文章很长,我深表歉意。我已经花了几天的时间了,我对下一步的工作感到困惑。

解决方法

您会看到以下行:

kotlinx.serialization.json.JsonDecodingException: Unexpected JSON token at offset -1: Failed to parse 'int'.

发生JsonDecodingException异常,这就是为什么它没有给出正确的响应。您必须检查所有数据类都是JSON对象中的相同变量。

我在您的数据类中发现1个问题,首先检查此JSON Reposne:

"amount": 1.5

现在检查您的数据类,该数据类具有var amount: Int = 0

@Serializable
data class Ingredient(
    var amount: Int = 0,var name: String? = null,var original: String? = null,// Original text of the ingredient
    var unit: String? = null,var unitLong: String? = null,var unitShort: String? = null
)

此处JSON对象位于Float中,而您正在其中存储Int,这可能会导致异常。确保数据类中的所有值都正确。

或者要解决此问题,只需将String设置为数据类中的所有变量以检查所有响应是否正确,然后再根据需要将它们转换为Int,Float。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?