Gson或Moshi:在POJO领域可以有两种类型,如何保存到任何领域

编辑:

这是我有的JSON字符串:

json#1 { [ { field1 : "" field2 : 0 field3 : "Amount not fixed" or field : 250 // this field can be string or int }, { field1 : "" field2 : 0 field3 : "Amount not fixed" or field : 250 // this field can be string or int } ] } json#2 { field1 : "" field2 : 0 field3 : "Amount not fixed" or field : 250 // this field can be string or int } 

或者它可以从服务器的任何json字符串。 这里的重点是可能有一个或多个可能有动态值的字段(这种情况下,field3可以是字符串或int)

然后我想将它们反序列化到任何POJO

 class Temp1 { // field1 here // field2 here @SerializedName("field3") val field3Int: Int? = null @SerializedName("field3") val field3String: String? = null } 

这意味着如果从服务器发送的值是一个Int ,我想设置值为field3Int 。 如果是String ,则设置为field3String

可能有其他的POJO将会拥有这些可能具有动态价值的领域。

感谢Serj的回答,但我仍然无法在编辑问题后显示我的真实情况后,在TypeAdapter类上工作。

顺便说一句。 我使用这个与Retrofit2像这样:

 val moshi = Moshi.Builder() .add(MultitypeJsonAdapterAdapter()) .build() return Retrofit.Builder().baseUrl(baseUrl) .addConverterFactory(MoshiConverterFactory.create(moshi)) .client(httpClient.build()) .build() 

借助Moshi您可以利用多态反序列化功能。 只需编写一个将使用JsonReader#readJsonValue()的自定义适配器。 见下面的代码:

 data class Multitype constructor(val fieldInt: Int?, val fieldString: String?) { constructor(fieldInt: Int) : this(fieldInt, null) constructor(fieldString: String) : this(null, fieldString) } class MultitypeJsonAdapterAdapter { @FromJson fun fromJson(reader: JsonReader): Multitype { val jsonValue = reader.readJsonValue() as Map<String, Any?> val field = jsonValue["field"] return when (field) { is String -> Multitype(field) is Double -> Multitype(field.toInt()) // readJsonValue parses numbers as Double else -> throw JsonDataException("Expected a field of type Int or String") } } @ToJson fun toJson(writer: JsonWriter, value: Multitype?) { TODO("not implemented") } } class MultitypeJsonAdapterAdapterTest { @Test fun check() { val moshi = Moshi.Builder() .add(MultitypeJsonAdapterAdapter()) .add(KotlinJsonAdapterFactory()) .build() val adapter = moshi.adapter(Multitype::class.java) val fromJson1 = adapter.fromJson("""{ "field": 42 }""") assertThat(fromJson1).isEqualTo(Multitype(42)) val fromJson2 = adapter.fromJson("""{ "field": "test" }""") assertThat(fromJson2).isEqualTo(Multitype("test")) } } 

我想我得到了我想要达到的。 而且不需要使用任何适配器。 如果一个字段可以有任何动态类型,则需要在POJO中将其声明为Any。 那么如果你想使用它的实际价值,你只需要检查它的类型和投它。 所以POJO应该这样:

 class Temp1 { // field1 here // field2 here @SerializedName("field3") val field3: Any? = null fun getField3Str() : String { return when (field3) { is String -> field3 as String is Int -> { "%d".format(field3 as Int) } else -> "" } } }