如何在Moshi中解析多种类型的json列表 [英] How to parse a json list of multiple type in Moshi
问题描述
得到一个混合了纯String和Image对象的json列表,如下所示:
Got a json list mixed with plain String and Image object like this:
{
"mixList": [
"string",
{
"imageUrl": "http://...",
"height": 320,
"width": 480
}
]
}
如何与Moshi解析?
How to parse with Moshi?
我希望有一个List<Data>
,
其中StringData extends Data
和ImageData extends Data
I would expect to have a List<Data>
,
where StringData extends Data
and ImageData extends Data
推荐答案
我已经解决了使用Moshi
和CustomAdaptor
的问题.经过大量研究,我无法找到更好的即用型"解决方案.解决方案.此解决方案位于kotlin
中,但也可以轻松移植到Java.
I've solved this problem using Moshi
with a CustomAdaptor
. After a lot of research I wasn't able to find a better "out-of-the-box" solution. This solutions is in kotlin
but can easily be ported to Java as well.
首先让我们定义我们要在此处解析的类型.我将调用包装器类型,其中包含mixList
,Response
:
First let's define the types we are trying to parse here. I'll call the wrapper type, that contains the mixList
, Response
:
@JsonClass(generateAdapter = true)
data class Response(val mix_types: Data)
以及可以在列表StringData
和ImageData
中的2种不同类型:
And the 2 different types that can be inside the list StringData
and ImageData
:
sealed class Data {
data class StringData(val value: String) : Data()
@JsonClass(generateAdapter = true)
data class ImageData(
val imageUrl: String,
val height: Int,
val width: Int
) : Data()
}
由于我使用的是Moshi代码源,因此我在Response
和ImageData
处加上了@JsonClass(generateAdapter = true)
注释,以便Moshi会为这些类型的适配器生成适配器(我将在我的自定义适配器中使用它)
As I'm using Moshi code-gen, so I have annotated Response
and ImageData
with @JsonClass(generateAdapter = true)
so that Moshi will generate the adapters for these types(and I'll leverage this in my custom adapter).
我想为Data
类型提供自己的自定义适配器,并且我也不希望Moshi为StringData
类型生成适配器,因为这正是我要序列化/反序列化为字符串,所以我不会注释这些类.
I want to provide my own custom adapter to the Data
type, and I won't also want the adapter Moshi would generate for the StringData
type, since this is precisely what I want to serialise/deserialise into a String, so I won't annotate these classes.
现在我要像这样编写我的自定义适配器:
Now I'm gonna write my custom adapter like this:
class DataCustomAdapter {
@FromJson
fun fromJson(jsonReader: JsonReader, delegate: JsonAdapter<ImageData>): Data? {
return if (jsonReader.peek() == BEGIN_OBJECT) {
delegate.fromJson(jsonReader)
} else {
StringData(jsonReader.nextString())
}
}
@ToJson
fun toJson(jsonWriter: JsonWriter, data: Data, delegate: JsonAdapter<ImageData>) {
when (data) {
is ImageData -> delegate.toJson(jsonWriter, data)
is StringData -> jsonWriter.value(data.value)
}
}
}
现在所缺少的就是向Moshi注册自定义适配器:
all it's missing now is to register the custom adapter with Moshi:
private val moshi = Moshi.Builder()
.add(DataCustomAdapter())
.build()
这篇关于如何在Moshi中解析多种类型的json列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!