[英]Java JSON Deserialize when type is String or List<String>
Is there a simple way to deserialize a value that may be either a String
or a List<String>
? 是否有一种简单的方法来反序列化可能是
String
或List<String>
?
I have to process a large JSON that I'll abbreviate like: 我必须处理一个我将缩写为的大型JSON:
{"A": {"item1": 1,
...
"itemN": "SomeString",
...
"itemM": 123.45},
"B": { ... },
"C": { ... },
}
And sometimes it looks like this: 有时它看起来像这样:
{"A": {"item1": 1,
...
"itemN": ["SomeString1", "SomeString2"],
...
"itemM": 123.45},
"B": { ... },
"C": { ... },
}
I deserialize with: 我反序列化:
MyData data = new Gson().fromJson(rxJSON, DataClass.class);
Where DataClass: DataClass的位置:
@Parcel
public class DataClass {
@SerializedName("A")
private AClass groupA;
@SerializedName("B")
private BClass groupB;
@SerializedName("C")
private BClass groupC;
... getters/setters ...
}
and AClass: 和AClass:
@Parcel
public class AClass {
@SerializedName("item1")
private int item1;
...
@SerializedName("itemN")
private List<String> itemN;
...
@SerializedName("itemM")
private float itemM;
... getters/setters ...
}
Ideally, I'd like to use AClass
for both JSONs, and in the case where itemN
is a String
, simply treat it as if it were a single element List<String>
(ie. treat "SomeString"
as ["SomeString"]
). 理想情况下,我想对两个JSON使用
AClass
,并且在itemN
是String
的情况下,只需将它视为单个元素List<String>
( "SomeString"
视为["SomeString"]
)。 After deserializing, I always want to access it as a list for simplicity in the rest of my code. 反序列化后,我总是希望在其余代码中将其作为简单列表进行访问。
I've seen suggestions for Polymophism solutions and solutions suggesting attempting to deserialize with one version of a class assuming one type (such as String
) and in an exception catch deserialize with a version of the class assuming the other type (such as List<String>
). 我已经看到了对Polymophism解决方案和解决方案的建议,建议尝试使用一个类的一个版本(如
String
)反序列化,并在异常中使用假定其他类型的类的版本反序列化反序列化(例如List<String>
)。 Other solutions suggest a more manual/piece-wise deserialization where it would deserialize only one level of the JSON hierarchy at a time until I came to itemN
and then check it's type. 其他解决方案建议更多手动/分段反序列化,它一次只反序列化JSON层次结构的一个级别,直到我来到
itemN
然后检查它的类型。 It seems like there should be a simpler way. 似乎应该有一个更简单的方法。 Is there?
在那儿?
I found a good solution thanks to: https://stackoverflow.com/a/31563539/3571110 and https://stackoverflow.com/a/6205384/3571110 我找到了一个很好的解决方案,感谢: https : //stackoverflow.com/a/31563539/3571110和https://stackoverflow.com/a/6205384/3571110
The first link shows using a custom deserializer for the entire JSON (too much work for me), and within that manages String
to List<String>
. 第一个链接显示为整个JSON使用自定义反序列化器(对我来说太多工作),并在其中管理
String
to List<String>
。 The second link gave me the insight that I could make a custom deserializer for basic types like List<>
(I previously thought I could only use custom classes). 第二个链接让我了解了我可以为
List<>
等基本类型创建自定义反序列化器(我之前认为我只能使用自定义类)。 Combining those ideas and making the appropriate changes yields (everything else staying the same): 结合这些想法并做出适当的改变(其他一切保持不变):
Solution: 解:
public class ListOrStringDeserializer implements JsonDeserializer<List<String>> {
@Override
public List<String> deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
List<String> items = Collections.emptyList();
if (json.isJsonArray()) {
items = context.deserialize(json, List.class);
} else if (json.isJsonPrimitive()) {
items = Collections.singletonList((String) context.deserialize(json, String.class));
}
return items;
}
}
Then register before deserializing: 然后在反序列化之前注册:
Gson gson = new GsonBuilder().registerTypeAdapter(new TypeToken<List<String>>() {}.getType(), new ListOrStringDeserializer()).create();
MyData data = gson.fromJson(rxJSON, DataClass.class);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.