鉴于所有关于 Moshi 的帖子以及人们(包括我自己)对如何解析列表的困惑,我不敢相信这是如此困难。我有一个有两个嵌套列表的对象。我无法让它们中的任何一个解析。
{
"respondent_id": "1",
"completion_status": "completed",
"date_modified": "2023-12-05T17:41:49Z",
"date_start": "2023-12-05T17:41:41Z",
"responses": [
{
"page_index": 0,
"page_id": "4771",
"question_id": "1645",
"question_index": 0,
"question_value": "Do you like me?",
"answers": [
{
"row_index": 0,
"row_id": "1",
"row_value": "",
"column_index": 10,
"column_id": "1",
"column_value": "Absolutely!"
}
]
},
{
"page_index": 0,
"page_id": "4771",
"question_id": "1614",
"question_index": 1,
"question_value": "What's the primary reason for your rating?",
"answers": [
{
"text_response": "Because you are cool"
}
]
},
{
"page_index": 0,
"page_id": "4771",
"question_id": "1614",
"question_index": 2,
"question_value": "How much do you like me?",
"answers": [
{
"row_index": 0,
"row_id": "1182",
"row_value": "More than anyone else"
}
]
}
]
}
所以我创建了这些数据类来解析它:
@JsonClass(generateAdapter = true)
data class SurveyResponse(
@SerializedName("respondent_id") val respondentId: String,
@SerializedName("completion_status") val completionStatus: String,
@SerializedName("date_modified") val dateModified: String,
@SerializedName("date_start") val dateStart: String,
@Json(name = "responses") val responses: List<SurveyQuestion>
)
@JsonClass(generateAdapter = true)
data class SurveyQuestion(
@SerializedName("page_index") val pageIndex: Int,
@SerializedName("page_id") val pageId: String,
@SerializedName("question_id") val questionId: String,
@SerializedName("question_index") val questionIndex: Int,
@SerializedName("question_value") val questionValue: String,
@Json(name = "answers") val answers: List<Answer>
)
@JsonClass(generateAdapter = true)
data class Answer(
@SerializedName("row_index") val rowIndex: Int,
@SerializedName("row_id") val rowId: String,
@SerializedName("row_value") val rowValue: String = "",
@SerializedName("column_index") val columnIndex: Int,
@SerializedName("column_id") val columnId: String,
@SerializedName("column_value") val columnValue: String
)
我什至尝试创建一些自定义适配器,尽管我没有理由相信它们是必要的:
class ResponsesAdapter {
@FromJson
fun arrayListFromJson(list: List<SurveyQuestion>): ArrayList<SurveyQuestion> = ArrayList(list)
}
class AnswersAdapter {
@FromJson
fun arrayListFromJson(list: List<Answer>): ArrayList<Answer> = ArrayList(list)
}
然后编写这段代码来解析它:
val moshi: Moshi = Moshi
.Builder()
.add(ResponsesAdapter())
.add(AnswersAdapter())
.build()
val jsonAdapter: JsonAdapter<SurveyResponse> = moshi.adapter<SurveyResponse>()
val surveyResponse = jsonAdapter.fromJson(jsonString)
我尝试了许多其他方法来创建自定义适配器,但我总是收到此错误,我在许多其他帖子中看到过该错误:
java.lang.IllegalArgumentException: No JsonAdapter for java.util.ArrayList<java.lang.String>,您可能应该使用 List 而不是 ArrayList (Moshi 默认情况下仅支持集合接口),或者注册自定义 JsonAdapter。
这条消息特别令人困惑,因为没有涉及 ArrayList,也没有字符串(除了我试图解析的原始字符串之外)。
我已经到了把东西扔到墙上看看什么能粘住的地步。这个问题解决起来并不是那么困难,但我没有看到解决方案。
编辑
跟进下面法鲁克的回答。我曾尝试使用KotlinJsonAdapterFactory
,但该行写错了。我写.adapter<SurveyResponse::class.java>()
。一旦我解决了这个问题,应用程序就不再崩溃了。
他解决此问题的答案的另一部分是将数据类中的注释从: 更改为
@SerializedName("whatever")
:
@Json(name = "whatever")
如果没有这个,所有值都会被解析为空。
首先,您应该处理这些值可以为空。
您不需要适配器。只需使用
KotlinJsonAdapterFactory()