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

Android Kotlin解析JSON到模型类时遇空字符串异常求助

解决Retrofit+Gson转换JSON到模型类时的"empty String"异常

API调用成功且能拿到完整JSON,但转模型类时触发"empty String"异常,两种Retrofit回调方式都出现问题,可按以下步骤排查解决:

1. 检查模型类字段与JSON的类型匹配

  • 核心问题大概率是JSON中的空字符串字段对应了模型类里的基本数据类型(比如JSON里是"",模型类定义成Int),Gson无法将空字符串转换为基本类型,直接抛出异常。
  • 把模型类中的基本类型换成Kotlin可空包装类(Int→Int?、Long→Long?),同时确保@SerializedName的字段名和JSON完全一致,避免字段名不匹配导致的隐性解析错误。

2. 配置自定义Gson实例,兼容空字符串解析

创建支持空字符串转默认值或null的Gson实例,替换Retrofit默认的Gson:

// 自定义Gson配置
val gson = GsonBuilder()
    .setLenient() // 宽松解析,兼容部分格式不严谨的JSON
    .registerTypeAdapter(Int::class.java, object : TypeAdapter<Int>() {
        override fun write(out: JsonWriter, value: Int?) {
            out.value(value)
        }

        override fun read(`in`: JsonReader): Int {
            return when (`in`.peek()) {
                JsonToken.NULL -> {
                    `in`.nextNull()
                    0 // 空值时返回默认值,也可以根据需求返回null(需改成Int?)
                }
                JsonToken.STRING -> {
                    val str = `in`.nextString()
                    if (str.isEmpty()) 0 else str.toInt()
                }
                else -> `in`.nextInt()
            }
        }
    })
    // 同理可以给Long、Double等类型添加适配器
    .create()

// Retrofit初始化时使用该Gson
val retrofit = Retrofit.Builder()
    .baseUrl(BASE_URL)
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build()

3. 定位具体出错的字段

如果数据量太大,可通过分段解析缩小范围:

// 在回调中先把JSON转成字符串,再逐个解析可疑字段
override fun onResponse(call: Call<JsonElement>, response: Response<JsonElement>) {
    val jsonStr = response.body().toString()
    val jsonObj = JsonParser.parseString(jsonStr).asJsonObject
    
    // 逐个测试可疑字段,比如先解析可能出问题的数值型字段
    val testNum = try {
        jsonObj.get("activity_id")?.asInt
    } catch (e: Exception) {
        e.printStackTrace() // 打印异常,定位字段
        null
    }
}

通过这种方式可以快速找到哪个字段的空字符串导致了解析失败。

4. 处理含空白字符的"空字符串"

有些JSON字段看似是空字符串,实际包含空格、换行等空白字符,可添加自定义适配器处理:

// 自定义字符串适配器,自动去除空白字符
class TrimStringAdapter : TypeAdapter<String>() {
    override fun write(out: JsonWriter, value: String?) {
        out.value(value?.trim())
    }

    override fun read(`in`: JsonReader): String {
        return `in`.nextString().trim()
    }
}

// 在模型类字段上使用该适配器
data class MyModelClass(
    @JsonAdapter(TrimStringAdapter::class)
    @SerializedName("activity_name")
    val activityName: String? = null,
    // 其他字段...
)

内容的提问来源于stack exchange,提问作者Urvish Stack

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:11:01