Moshi + Retrofit - 处理未知类型的 JSON 响应
Posted
技术标签:
【中文标题】Moshi + Retrofit - 处理未知类型的 JSON 响应【英文标题】:Moshi + Retrofit - Handling JSON response of unknown type 【发布时间】:2020-09-22 18:48:18 【问题描述】:我正在使用 Moshi,我有以下数据类
@JsonClass(generateAdapter = true)
data class A (
@Json(name = "_id")
val id: String?,
@Json(name = "b")
val b: B? = null
)
@JsonClass(generateAdapter = true)
data class B (
@Json(name = "_id")
val id: String?,
@Json(name = "foo")
val foo: String? = null
@Json(name = "c")
val c: C? = null
)
@JsonClass(generateAdapter = true)
data class C (
@Json(name = "_id")
val id: String?,
@Json(name = "bar")
val bar: String? = null
)
我的 API 有时将对象仅作为 ID 返回,而其他时候将其作为实际对象返回。例如,有时当我获取对象 A 时,它会返回
_id: "111111111",
b:
_id: "222222222",
foo: "foo",
c:
_id: "333333333",
bar: "bar"
但其他时候它可能会返回
_id: "111111111",
b: "222222222"
或
_id: "111111111",
b:
_id: "222222222",
foo: "foo",
c: "333333333"
如我们所见,它可能会返回一个表示对象的字符串,或填充的对象本身。如何创建自定义 Moshi 适配器来处理这个问题?如果它返回一个表示对象的 id,我希望它创建一个仅填充 id 并将其余字段设置为 null 的对象。
我尝试像这样创建一个自定义适配器
class bAdapter
@FromJson
fun fromJson(b: Any): B
return when (b)
is String -> B(b)
else -> b as B
但我得到了错误
com.squareup.moshi.JsonDataException: java.lang.ClassCastException: com.squareup.moshi.LinkedHashTreeMap cannot be cast to com.example.B
【问题讨论】:
【参考方案1】:如果有人遇到同样的问题,我通过使用漂亮的 @JsonQualifier 注释来解决它,如下所示:
@Retention(AnnotationRetention.RUNTIME)
@JsonQualifier
internal annotation class ObjectString
class ObjectStringAdapter
@FromJson
@ObjectString
fun fromJson(id: String): Object
return Object(id)
@ToJson
fun toJson(@ObjectString obj: Object): String
return obj.toString()
class ObjectAdapter
@FromJson
fun fromJson(jsonReader: JsonReader, @ObjectString stringAdapter: JsonAdapter<Object>, defaultAdapter: JsonAdapter<Object>): Object
return when (JsonReader.Token.STRING)
jsonReader.peek() ->
stringAdapter.fromJson(jsonReader)
else ->
defaultAdapter.fromJson(jsonReader)
!!
Object
是你的班级。
基本上创建了两个适配器,一个用于字符串,一个用于对象,并使用 jsonReader.peek() 来查看值并在运行时根据类型确定使用哪一个。
供参考:Moshi LocalDateTime adapter with multiple format
【讨论】:
以上是关于Moshi + Retrofit - 处理未知类型的 JSON 响应的主要内容,如果未能解决你的问题,请参考以下文章
使用 Moshi 和 Retrofit 将响应包装在另一个对象中
使用 Moshi 从 Retrofit 调用中没有得到任何结果
使用 Moshi/Retrofit2 访问深度嵌套的 JSON 数组