想象一下这个数据样本
"meta_data": [
{
"id": 40097,
"key": "_wcf_frm_created",
"value": ""
},
{
"id": 40098,
"key": "_wcf_custom_degin_checkbox",
"value": ""
},
{
"id": 40099,
"key": "_wcf_frm_data",
"value": {
"1": {
"1": "",
"2": "",
"3": "chk_box"
}
}
},
{
"id": 40119,
"key": "_vendor_select",
"value": "6484"
},
{
"id": 40120,
"key": "_vendor_percentage",
"value": "1"
},
{
"id": 40121,
"key": "_vendor_pro_cat",
"value": "Accessories"
}
]
Meta_data 中的值可以有多种类型。在我使用的生成器中,数据类型应该像这样创建。
sealed class Value {
class StringMapMapValue(val value: Map<String, Map<String, String>>) : Value()
class StringValue(val value: String) : Value()
}
对于 Moshi,我知道您必须在数据类之上添加 @JsonClass(generateAdapter = true) 。因此我有这样的东西
@JsonClass(generateAdapter = true)
data class MetaDatum (
val id: Long,
val key: String,
val value: Value
)
@JsonClass(generateAdapter = true)
sealed class Value {
class StringMapMapValue(val value: Map<String, Map<String, String>>) : Value()
class StringValue(val value: String) : Value()
}
我想指出,完整的 json 比这大得多。然而,这是我唯一的问题。我也有一些枚举问题,但可以用字符串替换
我收到的错误是error: @JsonClass can't be applied to net......Activity.Value: must not be seal public static abstract class Value
因此我的问题是,我如何解码具有多种枚举类型的 json。
我会在这里添加这个,在 xCode(swift) 中,这就是我设法做到的。
enum Value: Codable {
case string(String)
case stringMapMap([String: [String: String]])
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode([String: [String: String]].self) {
self = .stringMapMap(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
throw DecodingError.typeMismatch(Value.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Value"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .string(let x):
try container.encode(x)
case .stringMapMap(let x):
try container.encode(x)
}
}
}
调用数据
fun retrieveMenu(sku: Int, SSLAuth: String)
{
doAsync {
val client = OkHttpClient().newBuilder()
.build()
val formBody: RequestBody = FormBody.Builder()
.build()
val request: Request = Request.Builder()
.url("https://carteapp.net/..................")
.method("Get", formBody)
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")
val gist =
gistJsonAdapter.fromJson(response.body!!.source())
println(gist)
}
}
}
private val moshi = Moshi.Builder().build()
private val gistJsonAdapter = moshi.adapter(BarcodeScannerActivity.WcProductCall::class.java)
@JsonClass(generateAdapter = true)
data class WcProductCall (
val id: Long,
...........
val metaData: List<MetaDatum>,
...
)