使用Retrofit与Bearer Token解析JSON响应返回null的解决办法
问题原因
从OkHttp日志能看到,服务器返回的响应是包含code、message、data的外层结构,且data是数组(列表)类型([]包裹),但你的代码存在两个关键错误:
- 未定义对应整个响应的实体类,直接用
DataItem接收完整响应 - Api接口声明返回单个
DataItem,但实际data是列表类型,导致Gson无法匹配映射,最终所有字段返回null
解决方案
1. 创建外层响应实体类
定义对应服务器完整响应结构的类,包含所有顶层字段:
@Parcelize data class ApiResponse( @field:SerializedName("code") val code: Int? = null, @field:SerializedName("message") val message: String? = null, @field:SerializedName("data") val data: List<DataItem>? = null ) : Parcelable
2. 修改Api接口的返回类型
将接口返回值从单个DataItem改为外层响应类ApiResponse:
interface Api { @GET("v1/media/list/image") suspend fun getImage(): ApiResponse }
3. 调整调用代码,正确解析数据
在协程中调用接口后,从ApiResponse中取出data列表,再操作其中的DataItem:
private val scope = CoroutineScope(Dispatchers.IO) private fun getNetworkResponse() { scope.launch { try { val response = api.getImage() val dataList = response.data if (!dataList.isNullOrEmpty()) { // 示例:获取第一个元素的name字段 val firstItem = dataList[0] Log.d(MY_TAG, "第一个数据项的name: ${firstItem.name}") } else { Log.d(MY_TAG, "数据列表为空") } } catch (e: IOException) { Log.e(MY_TAG, "网络异常: $e") } catch (e: HttpException) { Log.e(MY_TAG, "HTTP错误: $e") } } }
4. 验证注意事项
- 确保
SerializedName注解的字段名和服务器返回的键完全一致(比如data、name) - 若后续接口返回的
data为单个对象而非列表,需对应修改ApiResponse中data的类型为DataItem?
内容的提问来源于stack exchange,提问作者Dmitry Sergienko
相关产品推荐
相关产品推荐

