如何在Moshi中使用带有接口的PolymorphicJsonAdapterFactory?

时间:2019-12-30 07:07:50

标签: java json kotlin moshi

我有一个带有两种具体类型的接口,作为我模型的一部分,我想与Moshi进行序列化/反序列化。我的问题是我不完全了解PolymorphicJsonAdapterFactory是否真正适合我的用例。我查看了示例和一些博客文章,并且(如果我对它们的理解是正确的)所有这些文章似乎都指向一个事实,即您的界面应该在界面中具有一个字段,可让您确定类型。我正在使用现有的代码库,因此无法轻松添加一个字段,该字段使我可以通过某种字符串文字来确定其类型。

这是我处理Moshi代码的地方,我正在寻求有关是否正确使用PolymorphicJsonAdapterFactory的验证。注意:我在代码的moshi部分和我的模型中使用java。我的界面及其具体类型在kotlin中

String json = ...;

Moshi moshi = new Moshi.Builder()
.add(PolymorphicJsonAdapterFactory.of(PersonInterface.java, "")
            .withSubtype(BusinessPerson.java, "occupation")
            .withSubtype(PolicePerson.java, "rank")
)
.build();
JsonAdapter<MyModel> jsonAdapter = moshi.adapter(MyModel.class);

MyModel myModel = jsonAdapter.fromJson(json);

注意:我在代码的moshi部分和模型中使用java。我的界面及其具体类型在kotlin中

MyModel的定义如下

class MyModel {
    String month;
    PersonInterface person;
}

我在Kotlin中的界面和具体类:

Interface PersonInterface {
    val personsName: String?
}

data class BusinessPerson(
        override val personsName: String,
        val occupation: String?
) : PersonInterface

data class PolicePerson(
    override val personsName: String,
    val rank: String?
) : PersonInterface

目标是希望Moshi能够创建

class MyModel {
    String month;
    BusinessPerson person;
}

class MyModel {
    String month;
    PolicePerson person;
}

取决于人员字段是否包含occupation(这意味着它是BusinessPerson类型)还是是否包含字段rank(这意味着它是PolicePerson类型)。

1 个答案:

答案 0 :(得分:2)

PolymorphicJsonAdapterFactory.of(PersonInterface.java, "")
    .withSubtype(BusinessPerson.java, "occupation")
    .withSubtype(PolicePerson.java, "rank")

意味着每个人的JSON应该包含一个密钥"",而"occupation""rank"是此密钥的值,而不是您想要的密钥名称本身。所以例如它会编码

BusinessPerson("John", "CEO")

{"": "occupation", "personsName": "John", "occupation": "CEO"}

如果您要避免使用鉴别符字段,我认为您必须为此用例编写自己的适配器工厂。