Retrofit与Moshi:解析包含两个数组的JSON对象
嘿,我之前也碰到过类似的情况——API返回的结构和自己预期的完全不一样,确实有点头疼!不过别担心,用Retrofit+Moshi处理这种嵌套对象里的数组其实很简单,咱们一步步来解决:
第一步:先明确API返回的JSON结构
首先得先搞清楚Behance API返回的具体格式,你可以用Postman或者浏览器直接调用API确认,它的响应大概是这样的:
{ "primary_fields": [ {"id": 123, "name": "Graphic Design"}, {"id": 456, "name": "Illustration"} ], "secondary_fields": [ {"id": 789, "name": "3D Art"}, {"id": 101, "name": "Motion Graphics"} ] }
核心点是:整个响应是一个顶层对象,里面包含两个数组字段,而不是直接返回单一数组。
第二步:创建匹配JSON结构的数据类
你需要定义两个数据类:一个描述单个创意领域,另一个包裹两个数组的顶层响应类:
// 单个创意领域的数据类,匹配数组里的每个对象 data class Category( val id: Int, val name: String ) // 顶层响应类,完全匹配整个JSON对象的结构 data class BehanceFieldsResponse( @Json(name = "primary_fields") // 用注解映射JSON字段和驼峰命名的变量 val primaryFields: List<Category>, @Json(name = "secondary_fields") val secondaryFields: List<Category> )
小提示:如果你的变量名和JSON字段名完全一致(比如直接用
primary_fields当变量名),可以不用@Json注解,Moshi会自动匹配,但用驼峰命名+注解会更符合Kotlin的编码规范。
第三步:修改Retrofit接口方法
原本你可能写的是返回Call<List<Category>>,现在要改成返回顶层响应类的Call(用Coroutines的话更简洁):
interface BehanceApiService { // 传统Call方式 @GET("fields") // 替换成Behance API的实际端点 fun getCreativeFields(): Call<BehanceFieldsResponse> // 推荐用Coroutines方式 @GET("fields") suspend fun getCreativeFieldsCoroutine(): BehanceFieldsResponse }
第四步:发起请求并提取数组
现在调用API时,就能直接拿到包含两个数组的响应对象,轻松提取你需要的数据:
传统Call回调方式:
val apiService = Retrofit.Builder() .baseUrl("https://api.behance.net/v2/") // 替换成Behance API的Base URL .addConverterFactory(MoshiConverterFactory.create()) .build() .create(BehanceApiService::class.java) apiService.getCreativeFields().enqueue(object : Callback<BehanceFieldsResponse> { override fun onResponse(call: Call<BehanceFieldsResponse>, response: Response<BehanceFieldsResponse>) { if (response.isSuccessful) { val fieldsResponse = response.body() val primaryCategories = fieldsResponse?.primaryFields // 第一个创意领域数组 val secondaryCategories = fieldsResponse?.secondaryFields // 第二个创意领域数组 // 接下来就可以用这两个数组做业务逻辑了 } else { // 处理请求失败的情况 } } override fun onFailure(call: Call<BehanceFieldsResponse>, t: Throwable) { // 处理网络异常 } })
Coroutines协程方式(更简洁):
lifecycleScope.launch { try { val fieldsResponse = apiService.getCreativeFieldsCoroutine() val primaryCategories = fieldsResponse.primaryFields val secondaryCategories = fieldsResponse.secondaryFields // 在这里处理拿到的两个数组 } catch (e: Exception) { // 捕获并处理异常 } }
额外小技巧
如果你不确定JSON结构,可以把API返回的JSON字符串直接导入到「JSON转Kotlin类」工具里,一键生成匹配的数据类,避免手动编写出错。另外记得确认Gradle里已经添加了Retrofit和Moshi的依赖:
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-moshi:2.9.0' implementation 'com.squareup.moshi:moshi-kotlin:1.14.0' kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.14.0'
内容的提问来源于stack exchange,提问作者Josh Ribeiro
相关产品推荐
相关产品推荐

