Moshi的PolymorphicJsonAdapterFactory在withDefaultValue中如何获取类型标签?
原生PolymorphicJsonAdapterFactory提供的withDefaultValue方法本身不支持获取未匹配的类型标签,你可以通过以下两种方式实现需求:
方案1:自定义多态适配器(推荐)
在原有多态适配逻辑外层包一层自定义工厂,提前读取类型标签后再做匹配,匹配失败时直接获取标签做上报和兜底:
步骤1:定义兜底子类和通用字段
// 原有天气基类 sealed class Weather { // 存储实际返回的类型标签,方便后续逻辑使用 var actualTypeLabel: String? = null } data class ColdWeather(val temp: Int) : Weather() data class HotWeather(val temp: Int) : Weather() // 新增兜底未知天气类型 data class UnknownWeather(val label: String) : Weather()
步骤2:实现自定义适配器工厂
class WeatherPolymorphicFactory : JsonAdapter.Factory { // 复用原有多态适配逻辑 private val delegateFactory = PolymorphicJsonAdapterFactory.of(Weather::class.java, "type") .withSubtype(ColdWeather::class.java, "Cold") .withSubtype(HotWeather::class.java, "Hot") override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi): JsonAdapter<*>? { if (type != Weather::class.java) return null val delegateAdapter = delegateFactory.create(type, annotations, moshi) as JsonAdapter<Weather> return object : JsonAdapter<Weather>() { override fun fromJson(reader: JsonReader): Weather? { // 先读取完整Json节点,提取类型标签 val jsonNode = reader.readJsonValue() as? Map<String, Any?> ?: return null val typeLabel = jsonNode["type"] as? String val parseResult = delegateAdapter.fromJsonValue(jsonNode) return if (parseResult == null) { // 未匹配到类型,此处可直接执行上报逻辑 Log.e("API_ERROR", "未匹配的天气类型标签:$typeLabel") UnknownWeather(typeLabel.orEmpty()) } else { parseResult.actualTypeLabel = typeLabel parseResult } } override fun toJson(writer: JsonWriter, value: Weather?) { delegateAdapter.toJson(writer, value) } } } }
步骤3:替换原有配置
把你之前注册PolymorphicJsonAdapterFactory的逻辑,替换为注册上述自定义工厂即可。
方案2:轻量实现(无需自定义适配器)
如果不想改动适配逻辑,也可以直接在基类中声明类型标签字段,让Moshi正常反序列化该字段:
sealed class Weather { // 让Moshi直接反序列化type字段到该属性 val type: String? = null }
后续拿到反序列化结果后,判断如果是你通过withDefaultValue设置的兜底实例,直接读取type属性的值就能拿到未匹配的标签,再做上报即可。
内容的提问来源于stack exchange,提问作者c_idle
相关产品推荐
相关产品推荐

