【发布时间】:2019-08-05 15:54:33
【问题描述】:
在这一点上,这已经是一个老问题了,我可能已经阅读了关于 SO 的所有相关主题。
但切中要害。也许我需要一些建议或更正?
出于某种原因,我们有 2 种类型的可生成 Json:
{"data": {"id": "value"}} 和 {"data":[{"id": "value"}]}
对象和数组。还有其他参数,但它们在这里无关紧要。每个请求的“id”都不同。有时是 userId、portfolioId 等。所以我得到“id”并将其传递给相关的 var。
很长一段时间我都在处理第一个案例。并像这样创建 POJO:
Data.class
public class Data {
@SerializedName("id")
@Expose
private String id;
public Data() {
}
public Data(String id) {
super();
this.id = id;
}
protected String getId() {
return id;
}
我通过 User.class 处理“数据”参数。
@JsonAdapter(UserDeserializer.class)
public Data data;
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public User() {
}
public User(Data data) {
super();
this.data = data;
}
Gson gson = new Gson();
public String getPortfolioList(String tokenId, String userId) {
Call<User> call = apiRequest.getPortfolioList(userId, tokenId);
try {
User newResult = gson.fromJson(String.valueOf(call.execute().body()), User.class);
System.out.println(newResult.getData().getId());
} catch (IOException e) {
e.printStackTrace();
}
return getPortfolioId();
}
Deserializer.class
public class UserDeserializer implements JsonDeserializer<User> {
private Type listType = new TypeToken<List<Data>>(){}.getType();
@Override
public User deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
User user = new User();
JsonElement jsonElement;
if (json.isJsonArray()) {
jsonElement = json.getAsJsonArray();
user.data = context.deserialize(jsonElement,listType);
// user.data = new Gson().fromJson(jsonElement, new TypeToken<List<Data>>() {}.getType());
} else {
jsonElement = json.getAsJsonObject();
user.data = context.deserialize(jsonElement, Data.class);
// user.setData(new Gson().fromJson(jsonElement, new TypeToken<Data>() {}.getType()));
}
return user;
}
}
Gson builder 在 BaseApi 类中以防万一:
Gson gson = new GsonBuilder().registerTypeAdapter(UserDeserializer.class, new UserDeserializer()).setLenient().create();
如果没有自定义反序列化和数组 JSON 问题,这将完美运行。但现在我必须确定我得到的 "data" 的确切类型。
在上述情况下,我得到java.lang.ClassCastException: java.util.ArrayList cannot be cast to auto.Rest.Data
我假设我必须创建另一个 Data 类(例如会有 DataObject 和 DataArray)并像我一样描述每个参数在 Data.class 之前完成这项工作?我认为我在反序列化期间做错了,但我不确定在哪里。
或者我错了,可以调用 Data 作为 List 和 Data 作为 Object同一个班?
我已经为此工作了几天(?)并且正在考虑使用泛型而不是 Gson 帮助,是的,我很绝望。因此,任何帮助表示赞赏。
【问题讨论】:
-
{"data":[{"id": "value"}]}表示您可以拥有多个 id 的数组。在这种情况下,您的Data实例会是什么样子,例如为{"data":[{"id": "1"}, {"id": "2"}]}? -
user.data = context.deserialize(jsonElement,listType);无法工作,因为您正在反序列化List<Data>并试图将其分配给Data类型的字段。在这种情况下,您应该首先执行List<Data> dataList = context.deserialize(jsonElement,listType);之类的操作,然后从该列表中获取其中一个元素(如果有的话)并将其分配给user.data。 -
@Thomas 这是一个像这样的投资组合列表:
{"data": [{"id":"c87ca3fe85781007869b83f", "template": 0, "publish": false, "publication_at": null, "likes": 0, "liked": false, "comments": 0, "cells": { "data": [ {/*someting else*/}]}}, {/*another portfolio like the same above*/}]}我真的希望这是可以理解的。 -
@Thomas 谢谢。我会试试这个。我可以先将其分配给
user.data,然后再分配给后者的.getId()吗?或者我必须为List<Data>创建相同的方法? -
如果
Data可以使用开箱即用的映射反序列化,那么只需将数组反序列化为列表并从反序列化的元素中获取 id 就足够了。
标签: java json gson deserialization retrofit