You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin中Retrofit响应处理问题:无法解析用户ID及数据

解决Retrofit无法解析登录响应数据的问题

看起来你在Retrofit解析服务器返回的登录数据时遇到了障碍,我帮你梳理下几个核心问题和对应的解决办法:


1. 数据模型结构与服务器响应不匹配

你的Callback泛型用的是GetLoginAndRegisterResp,但实际服务器返回的JSON根结构应该对应你嵌套在里面的LoginResp类(包含user_info和status字段)。外层的GetLoginAndRegisterResp只是一个容器类,并不是真正的响应根对象,这会导致Retrofit无法正确映射数据。

解决办法:
把Callback的泛型改为GetLoginAndRegisterResp.LoginResp,或者直接调整模型结构,让LoginResp作为根数据类:

// 调整后的模型类(去掉外层容器,直接用LoginResp作为根)
data class LoginResp(
    @SerializedName("user_info") val userInfo: UserInfo = UserInfo(),
    @SerializedName("status") val status: Status = Status()
)

data class UserInfo(
    @SerializedName("user_id") val userId: String = "",
    @SerializedName("login_hash") val loginHash: String = "",
    @SerializedName("twitter_id") val twitterId: String = "",
    @SerializedName("full_name") val fullName: String = "",
    @SerializedName("photo_url") val photoUrl: String = "",
    @SerializedName("mobile") val mobile: String = ""
)

data class Status(
    @SerializedName("status_code") val statusCode: String = "",
    @SerializedName("status_text") val statusText: String = ""
)

然后更新Callback的泛型:

doApiLogin.getLogin(params).enqueue(object : Callback<LoginResp> {
    override fun onResponse(call: Call<LoginResp>?, response: Response<LoginResp>?) {
        if (response != null && response.isSuccessful) {
            val loginResp = response.body()
            loginResp?.let {
                // 现在可以正常获取用户ID和其他数据了
                val userId = it.userInfo.userId
                NajibApplication.instance.setLog("解析到的用户ID:$userId")
                NajibApplication.instance.setLog("登录状态:${it.status.statusText}")
            } ?: run {
                val statusCode = response.code()
                NajibApplication.instance.setLog("statusCode:" + statusCode)
            }
        } else {
            // 打印错误响应内容,方便排查
            response?.errorBody()?.let {
                NajibApplication.instance.setLog("错误响应内容:${it.string()}")
            } ?: run {
                NajibApplication.instance.setLog("请求失败>>>>")
            }
        }
    }

    override fun onFailure(call: Call<LoginResp>?, t: Throwable?) {
        NajibApplication.instance.setLog("请求失败>>>> ${t?.message ?: "未知错误"}")
    }
})

2. toString方法引用了已注释的字段

你的UserInfo类的toString方法里还在使用username、facebook_id这些已经被注释掉的字段,这会导致编译错误,即使你没主动调用toString,也会影响代码正常运行。

解决办法:
把toString里的注释字段全部移除,或者如果服务器确实返回这些字段,就取消对应字段的注释。比如修改后的UserInfo toString:

data class UserInfo(
    @SerializedName("user_id") val userId: String = "",
    @SerializedName("login_hash") val loginHash: String = "",
    @SerializedName("twitter_id") val twitterId: String = "",
    @SerializedName("full_name") val fullName: String = "",
    @SerializedName("photo_url") val photoUrl: String = "",
    @SerializedName("mobile") val mobile: String = ""
) {
    override fun toString(): String {
        return "UserInfo(userId='$userId', loginHash='$loginHash', twitterId='$twitterId', fullName='$fullName', photoUrl='$photoUrl', mobile='$mobile')"
    }
}

3. 确认Retrofit的Converter配置

确保你的Retrofit实例已经添加了Gson转换工厂,否则Retrofit无法自动将JSON转为Kotlin对象:

val retrofit = Retrofit.Builder()
    .baseUrl("你的API基地址")
    .addConverterFactory(GsonConverterFactory.create()) // 必须添加这一行
    .build()

4. 打印原始响应排查结构

如果还是无法解析,可以先打印服务器返回的原始JSON,确认结构是否和你的模型匹配:

override fun onResponse(call: Call<LoginResp>?, response: Response<LoginResp>?) {
    if (response != null) {
        // 打印原始响应内容
        val rawResponse = response.body()?.toString() ?: response.errorBody()?.string() ?: "空响应"
        NajibApplication.instance.setLog("原始响应:$rawResponse")
    }
}

通过对比原始JSON和你的模型字段,就能快速找到不匹配的地方。

内容的提问来源于stack exchange,提问作者NAP-Developer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:48:43