我很难解析JSON(与Moshi)的某些内部部分,这些部分可能相差很大,并且高度非结构化。总体看起来像这样:
response: {
items: [{
type: "typeA",
data: {
"1563050214700-001": {
foo: 123 ....
}
}
}, {
type: "typeB",
data: {
"1563050214700-002": {[
// differs a lot from previous one
{bar: 123 .... }
]}
}
}]
}
数据类结构如下:
data class Response(
val items: Map<String,List<Item?>>?
) {
data class Item(
val type: String?,
val data: Map<String,List<DataItem?>>?
) {
data class DataItem(
// members highly unstructured
)
}
}
“ DataItem”的架构变化很大。看起来Moshi codegen支持适配器,该适配器可能潜在地允许手动解析这些内部数据类,但是我找不到正确的教程或示例。理想情况下,我希望将整个Response解析为好像是定义良好的JSON。
这是我使用翻新/ moshi的方式
@Provides
@Singleton
@MyApp
fun provideMyAppRetrofit(context: Context, @MyApp okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(MoshiConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(context.getString(R.string.APP_BASE_URL))
.build()
}
@Provides
@Singleton
fun provideMyAppApiService(@MyApp retrofit: Retrofit): MyAppApiService {
return retrofit.create(MyAppApiService::class.java)
}
我该如何实现?任何示例或参考实现都会有所帮助。
答案 0 :(得分:1)
欢迎使用多态JSON解析问题一词!
我们正在编写自己的JSON适配器,如下所示:
internal class CardJsonAdapter(
moshi: Moshi
) : JsonAdapter<Card>() {
private val cardTypeAdapter = moshi.adapter(Card.Type::class.java)
private val amountsWithActionAdapter = moshi.adapter(AmountsWithActionCard::class.java)
private val backgroundImageCardAdapter = moshi.adapter(BackgroundImageCard::class.java)
@Suppress("TooGenericExceptionCaught")
override fun fromJson(reader: JsonReader): Card = try {
@Suppress("UNCHECKED_CAST")
val jsonMap = reader.readJsonValue() as Map<String, Any?>
val type = cardTypeAdapter.fromJsonValue(jsonMap["type"])
createCardWithType(type, jsonMap)
} catch (error: Exception) {
if (BuildConfig.DEBUG) {
Log.w("CardJsonAdapter", "Failed to parse card", error)
}
// Try not to break the app if we get unexpected data: ignore errors and return a placeholder card instead.
UnknownCard
}
override fun toJson(writer: JsonWriter, value: Card?) {
throw NotImplementedError("This adapter cannot write cards to JSON")
}
private fun createCardWithType(type: Type?, jsonMap: Map<String, Any?>) = when (type) {
null -> UnknownCard
Type.AMOUNTS_WITH_ACTION -> amountsWithActionAdapter.fromJsonValue(jsonMap)!!
Type.BACKGROUND_IMAGE_WITH_TITLE_AND_MESSAGE -> backgroundImageCardAdapter.fromJsonValue(jsonMap)!!
}
}
但是,它不再是必需的。 Moshi现在支持多态JSON解析-https://proandroiddev.com/moshi-polymorphic-adapter-is-d25deebbd7c5
答案 1 :(得分:0)
制作自定义适配器
class YourAdapter {
@FromJson
fun fromJson(reader: JsonReader, itemsAdapter: JsonAdapter<ItemsResponse>): List<ItemsResponse>? {
val list = ArrayList<ItemsResponse>()
if (reader.hasNext()) {
val token = reader.peek()
if (token == JsonReader.Token.BEGIN_ARRAY) {
reader.beginArray()
while (reader.hasNext()) {
val itemResponse = itemsAdapter.fromJsonValue(reader.readJsonValue())
itemsResponse?.let {
list.add(itemResponse)
}
}
reader.endArray()
}
}
return list
}
}