问题描述
我如何使用Gson解析这个JSON?
我有一个包含多个对象类型的数组,我不知道需要创建哪种对象才能保存此结构。我无法更改json消息(我不控制服务器)。
函数(有点)是这个的唯一类
public class Response {
private List< Object> TR;
私人诠释结果;
(...)
}
JSON消息(请注意具有多种对象类型的数组。)
{
tr:
[
{
a:
{
userId:112
}
},
$ bb:
{
userId:123,
地址:街道假人
}
} ,
{
a:
{
userId:154
}
}
],
results:3
}
Gson用户手册明确涵盖了这一点:
您有一个字段为 tr $ c $的对象这是一个包含任意类型的数组。
用户指南解释说您不能直接反序列化这样的结构,并推荐:
在你的情况下......它将取决于该数组中可能的对象。如果他们都将拥有相同的内部对象,那么您会想要做类似...
List< MyUserPojo> list = new ArrayList< MyUserPojo>();
JsonArray array = parser.parse(json).getAsJsonObject()。getAsJsonArray(tr); (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
和结果
字段。
class MyPojo
{
List< MyUserPojo>用户列表;
int结果;
}
class MyUserPojo
{
String userId;
字符串地址;
}
类MyDeserializer实现了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); (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;
$ / code $ / pre
现在你全都设定了 - 你可以使用反序列化器并创建你的对象:
$ pre $ g $ g $ gson = new GsonBuilder()
.registerTypeAdapter(MyPojo.class,new MyDeserializer ())
.build();
MyPojo mp = gson.fromJson(json,MyPojo.class);
如果 a
, b
等都很重要......好吧,你必须弄清楚。但是上面的内容会让你很好地理解处理你的JSON结构需要什么。
为了完整起见,围绕这个唯一的哈克方式是,如果这些类型的数量相当有限,并且内部对象在它的方面也相当有限领域。您可以创建一个包含所有可能性的POJO:
class MyPojo
{
MySecondPojo a;
MySecondPojo b;
...
MySecondPojo f;
}
class MySecondPojo
{
String userId;
字符串地址;
...
字符串someOtherField;
}
当Gson反序列化JSON时,它会设置POJO中缺少的字段,到 null
。你现在可以在你的POJO中拥有 tr
为 List
或这些数组。再次强调一下,这真的很诡异,而且是错误的做法,但我想我会解释直接解析该数组需要做什么。
How can I parse this JSON using Gson?I have an array with multiple object types and I don't know what kind of object I need to create to save this structure. I cannot change the json message (I don't control the server).
The only class that function (sort of) was this
public class Response {
private List<Object> tr;
private int results;
(...)
}
JSON Message (Note the array with multiple object types.)
{
"tr":
[
{
"a":
{
"userId": "112"
}
},
{
"b":
{
"userId": "123",
"address":"street dummy"
}
},
{
"a":
{
"userId": "154"
}
}
],
"results":3
}
The Gson User's Guide explicitly covers this:
You have an object with a field tr
that is an array containing arbitrary types.
The users guide explains that you can't directly deserialize such a structure, and recomends:
In your case ... it would really depend on what objects were possible in that array. If they are all going to have that same inner object you'd want to do something like...
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);
}
And of course, this would need to be inside a custom deserializer for your actual object that would have the tr
and results
fields.
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;
}
}
Now you're all set - you can use that deserializer and create your object:
Gson gson = new GsonBuilder()
.registerTypeAdapter(MyPojo.class, new MyDeserializer())
.build();
MyPojo mp = gson.fromJson(json, MyPojo.class);
If the a
, b
etc are important ... well, you'll have to figure that out. But the above should get you well on your way to understanding what's going to be needed to deal with your JSON structure.
For completeness sake, the only "hacky" way around this is if there is a fairly limited number of those types and the inner object also is fairly limited in terms of its fields. You could create a POJO that encompasses all the possibilities:
class MyPojo
{
MySecondPojo a;
MySecondPojo b;
...
MySecondPojo f;
}
class MySecondPojo
{
String userId;
String address;
...
String someOtherField;
}
When Gson deserializes JSON it will set any missing fields in your POJO(s) to null
. You could now have tr
be a List
or array of these in your POJO. Again and to emphasize, this is really quite hacky and the wrong way to do it, but I thought I'd explain what would be required to directly parse that array.
这篇关于Gson使用不同对象类型的数组解析Json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!