有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用Moshi反序列化可以是两种数据类型之一的字段

我从OrientDB服务器接收到一些JSON,看起来像这样:

{
    ...
    "out": ...,
    "in": ...,
    ...
}

现在这两个字段outin可以是两种类型中的一种:String和我自己的自定义对象(让我们称之为Record)。例如,对于一个请求,我可能会收到以下内容:

{
    ...
    "out": "#17:0",
    "in": {
        ...
    },
    ...
}

另一方面,我可能会得到:

{
    ...
    "out": {
        ...
    },
    "in": "#18:2",
    ...
}

等等。两者都可能是String,两者都可能是Records,一个可能是String,另一个可能是Record,等等。现在,当我使用Moshi反序列化这种JSON时,我有两个参数outin来保存它们各自键的值;但是,因为这些值不是固定的数据类型,所以说起来容易做起来难

创建多个POJO(我想是“POKO”,因为我使用的是Kotlin)是行不通的,因为这些对象可以在其他JSON对象中找到。我需要一个对象,这些参数可以采用变量数据类型。那我该怎么做呢

我是否需要在Moshi中编写自定义适配器来序列化/反序列化这些值?如果是这样,我将如何编写一个可以根据参数值指定特定数据类型的文件?或者我可以找到/编写某种Kotlin类/函数/扩展函数来保存两种可能的数据类型

如果相关的话,我也在使用Reformation 2+RxJava 2异步进行HTTP调用,所以如果这些库中有任何数据类型或函数可以实现类似的功能,我洗耳恭听

即使有人只能用Java回答,也没关系,因为我可以自己转换代码。如果我遗漏了一些明显的东西,我会提前道歉


共 (1) 个答案

  1. # 1 楼答案

    你可以像我在这个答案中所做的那样:https://stackoverflow.com/a/65106419/3543610

    基本上,您将创建一个密封类,作为属性inout的类型。您还需要将原语string one包装到一个包含string的类型中,这样就可以使它扩展密封类,如下所示:

    sealed class YourType {
        data class StringData(val value: String) : YourType()
    
        @JsonClass(generateAdapter = true)
        data class Record(
            val prop1: String,
            val prop2: Int
        ) : YourType()
    }
    

    然后,具有这些属性的模型将看起来像:

    @JsonClass(generateAdapter = true)
    data class Model(
        ...
        val in: YourType,
        val out: YourType,
        ...
    )
    

    最后,为YourType类型编写自定义适配器:

    class YourTypeCustomAdapter {
        @FromJson
        fun fromJson(jsonReader: JsonReader, delegate: JsonAdapter<Record>): YourType? {
            return if (jsonReader.peek() == BEGIN_OBJECT) {
                delegate.fromJson(jsonReader)
            } else {
                StringData(jsonReader.nextString())
            }
        }
    
        @ToJson
        fun toJson(jsonWriter: JsonWriter, yourType: YourType, delegate: JsonAdapter<Record>) {
            when (yourType) {
                is Record -> delegate.toJson(jsonWriter, yourType)
                is StringData -> jsonWriter.value(yourType.value)
            }
        }
    }
    

    并在Moshi注册:

    private val moshi = Moshi.Builder()
        .add(YourTypeCustomAdapter())
        .build()