Kotlin使用Retrofit获取API响应中UsuarioId与Correo字段的方法
问题分析与解决步骤
1. 修正数据模型类
当前数据模型存在两个核心问题:一是未包含API返回的recordset等字段,二是@SerializedName与JSON字段大小写不匹配,同时缺失字段未做可空处理会导致解析失败。修正后的模型如下:
data class ResponseLogin( val recordsets: List<List<Recordset2>>, val recordset: List<Recordset2>, // 新增API返回的该字段 val output: Map<String, Any>, val rowsAffected: List<Int>, val returnValue: Int ) data class Recordset2( val Activo: Boolean? = null, // 设为可空并给默认值,JSON无此字段 @SerializedName("Correo") val Correo: String, // 匹配JSON的大写首字母字段 val IdDepartamento: Int? = null, val IdEmpleado: Int? = null, val IdEmpresa: Any? = null, val IdPlaza: Int? = null, val IdPuesto: Int? = null, val Nombre: String, val Plaza: String? = null, val UsuarioDominio: String, val UsuarioId: Int )
2. 修正Retrofit回调的取值逻辑
原代码错误使用response.message()(这是HTTP状态描述,如"OK")获取业务数据,同时未处理嵌套列表和空安全问题。修正后的回调代码如下:
retrofit.requestLogin(obj).enqueue(object : Callback<ResponseLogin> { override fun onResponse(call: Call<ResponseLogin>, response: Response<ResponseLogin>) { if (response.isSuccessful) { val loginResponse = response.body() ?: run { Toast.makeText(this@MainActivity, "响应数据为空", Toast.LENGTH_LONG).show() return } // 方式1:从嵌套的recordsets中提取数据 val userFromRecordsets = loginResponse.recordsets.firstOrNull()?.firstOrNull() userFromRecordsets?.let { val userId = it.UsuarioId val email = it.Correo Toast.makeText(this@MainActivity, "用户ID: $userId, 邮箱: $email", Toast.LENGTH_LONG).show() } // 方式2:从单层的recordset中提取数据(与recordsets数据一致) val userFromRecordset = loginResponse.recordset.firstOrNull() userFromRecordset?.let { val userId = it.UsuarioId val email = it.Correo // 可在此处将数据保存到变量或进行其他业务操作 } } else { Toast.makeText(this@MainActivity, "请求失败: ${response.code()}", Toast.LENGTH_LONG).show() } } override fun onFailure(call: Call<ResponseLogin>, t: Throwable) { Toast.makeText(this@MainActivity, "请求出错: ${t.message}", Toast.LENGTH_LONG).show() } })
关键说明
- 字段映射匹配:
@SerializedName必须与JSON字段完全一致(包括大小写),否则Retrofit无法正确映射值。 - 空安全处理:使用
firstOrNull()避免列表为空时抛出异常,通过?:和let处理可能的空值,符合Kotlin空安全规范。 - 数据获取方式:
response.body()才是解析后的业务数据,response.message()仅为HTTP状态描述,不能用于提取业务字段。 - 双数据源选择:API返回的
recordsets和recordset数据一致,可根据需求选择其中一种方式提取数据。
内容的提问来源于stack exchange,提问作者MexiCano
相关产品推荐
相关产品推荐

