Gson 用户指南明确涵盖了这一点:
https://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Collection-with-Objects-of-Arbitrary-Types
您有一个对象,其字段tr
是包含任意类型的数组。
用户指南解释说您不能直接反序列化这样的结构,并建议:
使用 Gson 的解析器 API(低级流解析器或 DOM 解析器 JsonParser)解析数组元素,然后对每个数组元素使用 Gson.fromJson()。这是首选方法。
在您的情况下......这实际上取决于该数组中可能有哪些对象。如果他们都将拥有相同的内在对象,你会想要做类似的事情......
List<MyUserPojo> list = new ArrayList<MyUserPojo>();
JsonArray array = parser.parse(json).getAsJsonObject().getAsJsonArray("tr");
for (JsonElement je : array)
{
Set<Map.Entry<String,JsonElement>> set = je.getAsObject().entrySet();
JsonElement je2 = set.iterator().next().getValue();
MyUserPojo mup = new Gson().fromJson(je2, MyUserPojo.class);
list.add(mup);
}
当然,这需要在您的实际对象的自定义反序列化器中,该对象将具有tr
andresults
字段。
class MyPojo
{
List<MyUserPojo> userList;
int results;
}
class MyUserPojo
{
String userId;
String address;
}
class MyDeserializer implements JsonDeserializer<MyPojo>
{
@Override
public MyPojo deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException
{
List<MyUserPojo> list = new ArrayList<MyUserPojo>();
JsonArray array = je.getAsJsonObject().getAsJsonArray("tr");
for (JsonElement je2 : array)
{
Set<Map.Entry<String,JsonElement>> set = je2.getAsObject().entrySet();
JsonElement je3 = set.iterator().next().getValue();
MyUserPojo mup = new Gson().fromJson(je3, MyUserPojo.class);
list.add(mup);
}
MyPojo mp = new MyPojo();
mp.tr = list;
mp.results = je.getAsObject().getAsJsonPrimitive("results").getAsInt();
return mp;
}
}
现在一切就绪 - 您可以使用该反序列化器并创建您的对象:
Gson gson = new GsonBuilder()
.registerTypeAdapter(MyPojo.class, new MyDeserializer())
.build();
MyPojo mp = gson.fromJson(json, MyPojo.class);
如果a
,b
等很重要……那么,您必须弄清楚这一点。但是上面的内容应该能让你很好地理解处理 JSON 结构需要什么。
为了完整起见,解决此问题的唯一“hacky”方法是,如果这些类型的数量相当有限,并且内部对象的字段也相当有限。您可以创建一个包含所有可能性的 POJO:
class MyPojo
{
MySecondPojo a;
MySecondPojo b;
...
MySecondPojo f;
}
class MySecondPojo
{
String userId;
String address;
...
String someOtherField;
}
当 Gson 反序列化 JSON 时,它会将 POJO(s) 中所有缺失的字段设置为null
. 你现在tr
可以在你的 POJO 中有一个List
或一个数组。再次强调一下,这真的很hacky并且是错误的方法,但我想我会解释直接解析该数组需要什么。