Retrofit2中如何将返回JSON的messageCode映射到父类BaseResponse的只读code字段
解决Retrofit2中子类无法将messageCode传递给父类code字段的问题
兄弟,咱们先把问题根源捋清楚:你当前的代码里,MyConcreteResponse构造函数的messageCode参数没加@SerializedName("messageCode")注解,Gson反序列化JSON的时候根本不知道要把返回的messageCode字段值赋值给这个参数。结果就是messageCode始终是null,而父类的code是Int非空类型,Kotlin自动把null转成了默认值0,这就是你看到code一直是0的原因。
下面给你两种实用的解决方案,按需选择就行:
方案一:给子类构造参数加SerializedName注解
直接给子类的messageCode参数标注对应的JSON字段名,让Gson能正确映射值,同时处理好空值情况:
如果后端保证messageCode永远不为null,直接改成非空类型:
class MyConcreteResponse( @SerializedName("messageCode") messageCode: Int, val data: List<String>? ) : BaseResponse(code = messageCode)
如果messageCode可能为null,要么把父类的code改成Int?,要么给个业务合理的默认值:
class MyConcreteResponse( @SerializedName("messageCode") messageCode: Int?, val data: List<String>? ) : BaseResponse(code = messageCode ?: 0) // 默认值可根据你的业务规则调整
方案二:扩展父类的SerializedName别名
如果多个接口会返回不同的code字段名(比如mc、code、messageCode),直接把messageCode加到父类的alternate别名列表里,父类自己就能解析这个字段,子类不用再传messageCode参数,代码更简洁:
修改父类:
open class BaseResponse( @SerializedName(value = "mc", alternate = ["code", "messageCode"]) val code: Int )
子类可以简化成:
class MyConcreteResponse(val data: List<String>?) : BaseResponse()
注意:如果父类构造参数没有默认值,需要给code加个默认值(比如val code: Int = 0),或者用Kotlin的noArg插件让Gson能创建无参实例(前者更简单直接)。
这两种方案都能确保code字段正确拿到messageCode的值,满足其他只读类的访问需求。
内容的提问来源于stack exchange,提问作者soigrames
相关产品推荐
相关产品推荐

