gpt4 book ai didi

android - Gson 使用具有不同对象类型的数组解析 Json

转载 作者:可可西里 更新时间:2023-11-01 18:44:53 36 4
gpt4 key购买 nike

如何使用 Gson 解析此 JSON?我有一个包含多种对象类型的数组,但我不知道需要创建哪种对象来保存此结构。我无法更改 json 消息(我不控制服务器)。

唯一(有点)起作用的类是这个

public class Response {
private List<Object> tr;
private int results;

(...)

}

JSON 消息(注意具有多种对象类型的数组。)

{
"tr":
[
{
"a":
{
"userId": "112"
}
},
{
"b":
{
"userId": "123",
"address":"street dummy"
}
},
{
"a":
{
"userId": "154"
}
}
],
"results":3
}

最佳答案

Gson 用户指南明确涵盖了这一点:

https://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Collection-with-Objects-of-Arbitrary-Types

您有一个对象,其字段 tr 是一个包含任意类型的数组。

用户指南解释说你不能直接反序列化这样的结构,并建议:

Use Gson's parser API (low-level streaming parser or the DOM parser JsonParser) to parse the array elements and then use Gson.fromJson() on each of the array elements. This is the preferred approach.

在您的情况下……这实际上取决于该数组中可能存在的对象。如果他们都将拥有相同的内部对象,您会想要做类似...

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);
}

当然,这需要在您的实际对象的自定义反序列化器中,该反序列化器将具有 trresults 字段。

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);

如果 ab 等很重要……好吧,你必须弄明白。但是上面的内容应该可以帮助您很好地理解处理 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 或这些列表的数组。再次强调,这确实很老套,而且是错误的做法,但我想我应该解释一下直接解析该数组需要什么。

关于android - Gson 使用具有不同对象类型的数组解析 Json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14713736/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com