使用@SerializedName配合Retrofit调用时MediaContentGroup对象缺失问题
解决Retrofit返回对象中嵌套字段未填充的问题
嘿,作为刚从Retrofit和Spring Boot的坑爬出来的开发者,太懂你这种“明明其他字段都正常,就嵌套对象空了”的崩溃了!别慌,咱们一步步排查:
1. 先确认「实际返回的JSON」和你的实体类完全匹配
别只信服务端说的@SerializedName没错,咱们自己抓包看真实响应才靠谱!
- 给OkHttp加个日志拦截器,直接在Logcat里看完整的响应JSON:
// Java版本 HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(loggingInterceptor) .build();
// Kotlin版本 val loggingInterceptor = HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } val client = OkHttpClient.Builder() .addInterceptor(loggingInterceptor) .build()
把这个client用到Retrofit初始化里,跑一遍接口,看Logcat里的响应JSON:
比如Photo对应的JSON是不是类似这样?
{ "id": "photo_001", "title": "春日花海", "mediaContentGroup": { "groupId": "mcg_001", "contentUrl": "https://xxx.com/photo.jpg" } }
对比你的MediaContentGroup类里的@SerializedName是不是和JSON里的键完全一致(包括大小写、下划线/驼峰格式),比如JSON里是groupId,你别写成group_id了!
2. 检查MediaContentGroup类本身的配置
这是新手最容易漏的细节:
- 必须有无参构造函数:Gson(Retrofit默认用的序列化库)需要无参构造来实例化对象。如果是Java类,手动写个
public MediaContentGroup() {};如果是Kotlin的data class,别加全参构造的限制,默认就有无参(或者补个@NoArgsConstructor注解)。 - 字段访问权限别卡死:Java类里的字段别设成
private又没写getter(Gson虽然能反射访问,但偶尔会出问题);Kotlin的data class直接用val/var就行,别乱加private修饰符。 - 嵌套结构别搞反:如果服务端返回的是
mediaContentGroup数组([]),你别在Photo类里定义成单个MediaContentGroup对象,反过来也一样!
3. 确认Retrofit的转换器配置没搞错
如果你换了序列化库,@SerializedName就失效了!比如:
- 用Gson的话,必须在Retrofit里加
addConverterFactory(GsonConverterFactory.create()) - 要是用了Moshi,就得用
@Json(name = "...")代替@SerializedName,并且添加Moshi的转换器
别混着用,新手很容易不小心加错转换器!
4. 试试开启Gson的严格模式排查
如果上面都没问题,给Gson加个严格模式,让它在序列化出错时直接抛出异常,能快速定位问题:
// Java Gson gson = new GsonBuilder() .setStrictness(Strictness.LENIENT) .serializeNulls() .create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create(gson)) .build();
// Kotlin val gson = GsonBuilder() .setStrictness(Strictness.LENIENT) .serializeNulls() .create() val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create(gson)) .build()
跑一遍接口,如果有字段不匹配,Logcat会直接抛出异常,告诉你哪个字段出了问题!
按这个顺序排查,90%的嵌套字段空值问题都能解决~
内容的提问来源于stack exchange,提问作者bdeane
相关产品推荐
相关产品推荐

