如何将含对象的JSON Object转换为JSON Array适配Retrofit数据类
解决JSON对象转List的Retrofit适配问题
问题场景
服务器返回的JSON结构如下:
{ "Items": { "zzzz": { "id": "zzzz", "title": "qqqqqqq", "notifications": [] }, "rrrrr": { "id": "rrrrr", "title": "rrrrrrrrrrrrrrrrrr", "notifications": [] }, "eeeee": { "id": "eeeee", "title": "eeeeeeeeeeeeeeeeeeee", "notifications": [] }, "wwww": null, "dddddd": { "id": "dddddd", "title": "ddddddddddddddddddddddddd", "notifications": [] }, "qqq": { "id": "qqq", "title": "qqqqqqqqqqqqqqqqqqqqqq", "notifications": [] }, "rrrrrr": null } }
本地Kotlin数据类定义:
data class Response( val Items: List<Notification> // 其他字段... ) data class Notification( val id : String, val title: String, val notifications: List<*> // 替换为实际类型 )
核心需求:将JSON中Items对象下的非null子对象转换为List<Notification>,适配Response的Items字段,且不能修改全局共用的OkHttp/Retrofit实例配置。
解决方案:局部自定义反序列化器
不需要全局修改反序列化配置,只需给Response的Items字段添加局部生效的自定义反序列化器即可。
1. 编写自定义反序列化器
实现Gson的JsonDeserializer接口,遍历JSON对象的所有值,过滤null并转换为Notification列表:
import com.google.gson.JsonDeserializationContext import com.google.gson.JsonDeserializer import com.google.gson.JsonElement import java.lang.reflect.Type class NotificationListDeserializer : JsonDeserializer<List<Notification>> { override fun deserialize( json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext? ): List<Notification> { val itemsJsonObject = json?.asJsonObject ?: return emptyList() return itemsJsonObject.entrySet() .map { it.value } .filterNotNull() // 过滤掉JSON中的null值(如wwww、rrrrrr) .filter { it.isJsonObject } // 确保元素是JSON对象类型 .mapNotNull { context?.deserialize(it, Notification::class.java) } // 转换为Notification对象 } }
2. 给Response的Items字段添加注解
在Response类的Items字段上标注@JsonDeserialize,指定使用上面的反序列化器:
import com.google.gson.annotations.JsonDeserialize data class Response( @JsonDeserialize(using = NotificationListDeserializer::class) val Items: List<Notification> // 其他字段... ) data class Notification( val id: String, val title: String, val notifications: List<*> // 替换为实际的嵌套类型 )
3. 效果说明
这个方案的优势在于:
- 反序列化器仅对Response类的Items字段生效,不会干扰其他接口的全局配置
- 自动过滤JSON中的无效null值,只保留有效的Notification对象
- 无需修改共用的OkHttp/Retrofit实例,完全适配你的场景
内容的提问来源于stack exchange,提问作者KudaGonsih
相关产品推荐
相关产品推荐

