Kotlin JSON解析: 模型转换实战指南
2025-01-16 20:42:42
JSON对象到Kotlin类模型的转换方法
数据交互中,常常会遇到将 JSON 数据转换成应用中可操作的对象的情况。在 Android 开发中,处理服务器返回的 JSON 数据并将其转换为 Kotlin 类模型是一个常见需求。这篇文章将分析一个实际案例,并提供有效的解决方案。
问题分析
开发者尝试将 JSON 数组转换成 QuestionModel
类的对象数组,但遇到了 com.google.gson.JsonSyntaxException: Expected a com.google.gson.JsonObject but was com.google.gson.JsonArray
错误。这表明 Gson 预期接收一个 JSON 对象,但实际上得到的是 JSON 数组。查看提供的代码可以发现,问题源于 answer_options
字段在 QuestionModel
中被定义为 JsonObject
类型,而实际 JSON 数据中 answer_options
是一个包含对象的 JSON 数组。
另外,JSON 数据结构的特性也是原因之一。“1”这个键对应的是一个 JsonArray, 里面是多个JsonObject, 而开发者试图将数组中每一个Json对象转换成QuestionModel
时发生错误,期望的是整体JsonArray, 而非每一个JsonObject.
解决方案一:修改数据模型
answer_options
实际上是一个数组,因此最直接的方法是修改 QuestionModel
类来匹配 JSON 数据结构。可以将 answer_options
的类型改为 List<AnswerOptionModel>
。 并且建立AnswerOptionModel
这个数据类。
data class AnswerOptionModel(
@SerializedName("id")
@Expose
var id: Int? = null,
@SerializedName("answer")
@Expose
var answer: String? = null
)
data class QuestionModel (
@SerializedName("question")
@Expose
var question: String? = null,
@SerializedName("id")
@Expose
var id: Int? = null,
@SerializedName("answer_options")
@Expose
var answer_options: List<AnswerOptionModel>? = null
)
代码示例
修改数据模型后,可以这样转换:
val testArray = tpsObject.getAsJsonObject("questions")[tpsSelection[0].toString()].asJsonArray
val questionList = Gson().fromJson(testArray.toString(), object : TypeToken<List<QuestionModel>>() {}.type) as List<QuestionModel>
questionList.forEach {
Log.i("m", it.question.toString())
}
上述代码的关键在于使用了 TypeToken
。它能正确地解析 JSON 数组为 List<QuestionModel>
。 forEach
循环用于打印每个问题的文字,便于调试。
解决方案二:手动遍历并解析
若由于特殊原因不能修改数据模型, 另一个方法就是遍历 JsonArray 并手动解析每个JsonObject,然后封装成集合。 这样的方法能够有效规避因模型定义问题引起的解析异常。
val testArray = tpsObject.getAsJsonObject("questions")[tpsSelection[0].toString()].asJsonArray
val questionList = mutableListOf<QuestionModel>()
for(i in 0 until testArray.size()){
val questionModel = Gson().fromJson(testArray[i].asJsonObject.toString(),QuestionModel::class.java)
questionList.add(questionModel)
}
questionList.forEach {
Log.i("m", it.question.toString())
}
该方法遍历数组, 将每一个JsonObject使用Gson转化为QuestionModel
实例, 添加到列表中. 使用forEach
循环打印 QuestionModel
实例的问题文本用于检查结果。
安全建议
- 类型匹配: 确保 Kotlin 数据模型中的字段类型与 JSON 数据中的类型完全匹配。类型不匹配会导致
JsonSyntaxException
错误。 - 容错处理: 对解析异常添加 try-catch 块,提高程序的健壮性。当出现解析错误的时候,及时处理。
总结
本文分析了 JSON 对象到 Kotlin 类模型的转换问题。通过修改数据模型或手动解析 JSON 数组两种方案,均可实现成功转换。选用哪种方式取决于实际需求和对代码可维护性的考虑。正确理解 JSON 结构并编写精确匹配的数据模型对数据处理至关重要。
这些策略在处理从服务器返回的JSON数据时提供有效的保障,确保数据被正确解析并转换为可操作的Kotlin对象。同时强调了匹配JSON数据结构和错误处理的重要性。