如何使用Moshi将json字符串序列化为org.json.JSONObject?

时间:2019-11-27 09:00:42

标签: json kotlin moshi

我从服务器收到的JSON响应本质上是动态的,因此无法将其映射到Kotlin数据类中。

我想从中创建一个org.json.JSONObject并从那里解析它。 我环顾了SO和Moshi的文档,但找不到实现这一目标的任何简单方法。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我最近偶然发现了同样的问题。我需要将一些新数据从一个端点重新发送到另一个端点。

服务器的响应如下:

{
    "someProperty": "value",
    "someOtherProperty": "otherValue",
    "someDynamicProperty": {
        // There may be anything including nested structures, not known beforehand
    }
}

通常,Moshi不对此类内容提供内置支持,但它允许您构建自己的适配器并处理解析逻辑。

您需要定义要作为结果接收的类型:

@JsonClass(generateAdapter = true)
data class CustomResponse(
    val someProperty: String,
    val someOtherProperty: String,
    val someDynamicProperty: JSONObject?
)

然后,您需要创建一个自定义适配器来处理解析:

internal object JSONObjectAdapter {

    @FromJson
    fun fromJson(reader: JsonReader): JSONObject? {
        // Here we're expecting the JSON object, it is processed as Map<String, Any> by Moshi
        return (reader.readJsonValue() as? Map<String, Any>)?.let { data ->
            try {
                JSONObject(data)
            } catch (e: JSONException) {
                // Handle error if arises
            }
        }
    }

    @ToJson
    fun toJson(writer: JsonWriter, value: JSONObject?) {
        value?.let { writer.value(Buffer().writeUtf8(value.toString())) }
    }
}

然后,只需在创建时将此适配器添加到Moshi builder中即可

Moshi.Builder().add(JSONObjectAdapter).build()

或如果只想将其应用于某些特定属性,则使用Moshi注释。