Retrofit反序列化JSON报错:缺失类鉴别器的多态序列化器未找到
问题:Kotlin+Retrofit POST请求触发多态序列化异常(未使用多态)
异常信息
kotlinx.serialization.json.internal.JsonDecodingException: Polymorphic serializer was not found for missing class discriminator ('null')
接口返回JSON
{"CustID":101,"DeviceID":81}
相关代码实现
数据类
@SerialName("NewCustVals") @Serializable data class NewCustVals ( @SerialName("CustID") var CustID: Int? = 0, @SerialName("DeviceID") var DeviceID: Int? = 0 )
Retrofit服务接口
interface LTECustomerInterface { companion object { private var TAG :String = "LTECustomerInterface" var BASE_URL = "http://XXXXXXXXXXX:XXXX/" //test server lateinit var callbackApi :ApiCallback @OptIn(ExperimentalSerializationApi::class) fun create(cb:ApiCallback): LTECustomerInterface { callbackApi = cb val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(Json{ignoreUnknownKeys = true; isLenient = true}.asConverterFactory( "application/json".toMediaType())) // .client(client) .build() return retrofit.create(LTECustomerInterface::class.java) } } @POST("/newCustomer") suspend fun newCustomer(@Body data : Customer ) :Call<NewCustVals> }
请求调用代码
fun sendCustomer() { viewModelScope.launch(Dispatchers.IO) { val call = serverCustomerHttpInterface.newCustomer(_currentCust.value) call.enqueue(object : retrofit2.Callback<NewCustVals>{ override fun onResponse(call: Call<NewCustVals>, response: Response<NewCustVals>) { Log.i(TAG,"NewCustomer onResponse called") } override fun onFailure(call: Call<NewCustVals>, t: Throwable) { Log.i("sendCustomer()","NewCustomer onFailure") } }) } }
排查思路
- 修正suspend函数返回值:Retrofit中标记为
suspend的接口方法,不能返回Call<T>,需直接返回NewCustVals或Response<NewCustVals>;若要使用enqueue回调,需去掉suspend关键字,保持返回Call<NewCustVals>。当前写法会导致序列化逻辑混乱,触发非预期的多态检查。示例修改:@POST("/newCustomer") suspend fun newCustomer(@Body data : Customer ) : NewCustVals - 检查
Customer类序列化配置:作为@Body参数的Customer类必须添加@Serializable注解,且内部无多态类型字段。若该类涉及继承,需正确配置kotlinx序列化多态规则,但根据描述应为简单数据类,先确认注解是否完整。 - 移除类级别的
@SerialName("NewCustVals"):该注解多用于多态场景标记类的鉴别器值,你的数据类直接对应返回JSON结构,无需此注解,移除可避免序列化器误判为多态类型。 - 调整JSON转换器配置:可显式补充序列化配置,避免默认多态逻辑干扰,示例:
Json { ignoreUnknownKeys = true isLenient = true explicitNulls = true }
内容的提问来源于stack exchange,提问作者userCB
相关产品推荐
相关产品推荐

