在这一点上,这已经是一个老问题了,我可能已经阅读了有关SO的所有相关主题。
但是要点。我需要一些建议或更正吗?
出于某种原因,我们有两种可生成的Jsons:
{"data": {"id": "value"}} 和 {"data":[{"id": "value"}]}
{"data": {"id": "value"}}
{"data":[{"id": "value"}]}
对象和数组。还有其他参数,但在这里无关紧要。每个请求的“ id”都不同。有时是userId,PortfolioId等。因此我得到“ id”并将其传递给相关的var。
很长一段时间我一直在处理第一种情况。并这样创建POJO:
数据类
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(); }
解串器类
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; } }
__BaseApi类中的 Gson构建器 ,以防万一:
Gson gson = new GsonBuilder().registerTypeAdapter(UserDeserializer.class, new UserDeserializer()).setLenient().create();
如果没有自定义反序列化和Array JSON问题,它将可以完美地工作。但是现在我必须确定我得到的“数据”的确切类型。
在上述情况下,我得到 java.lang.ClassCastException: java.util.ArrayList cannot be cast to auto.Rest.Data
java.lang.ClassCastException: java.util.ArrayList cannot be cast to auto.Rest.Data
我假设我必须创建另一个 Data 类(例如将有 DataObject 和 DataArray ),并像以前在 Data.class中 所做的那样描述每个参数,以完成这项工作?我想在反序列化过程中做错了什么,但是我不确定tbh在哪里。
还是我错了,可以将 Data 作为 List 进行调用并将 Data 作为同一类的 Object 进行调用?
我已经为此工作了好几天(?),并且正在考虑使用泛型而不是Gson帮助,是的,我很绝望。因此,任何帮助表示赞赏。
如果您一直有,object或者one-element array可以编写自定义反序列化器,如下所示:
object
one-element array
class OneOrElementJsonDeserializer<T> implements JsonDeserializer<T> { @Override public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { if (json instanceof JsonArray) { final JsonArray array = (JsonArray) json; final int size = array.size(); if (size == 0) { return null; } return context.deserialize(array.get(0), typeOfT); } return context.deserialize(json, typeOfT); } }
简化后的示例模型如下所示:
class User { @JsonAdapter(OneOrElementJsonDeserializer.class) private Data data; public User() { } public User(Data data) { super(); this.data = data; } public Data getData() { return data; } public void setData(Data data) { this.data = data; } @Override public String toString() { return "User{" + "data=" + data + '}'; } } class Data { private String id; protected String getId() { return id; } public void setId(String id) { this.id = id; } @Override public String toString() { return "Data{" + "id='" + id + '\'' + '}'; } }
用法示例:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.google.gson.annotations.JsonAdapter; import java.io.File; import java.io.FileReader; import java.lang.reflect.Type; public class GsonApp { public static void main(String[] args) throws Exception { File jsonFile = new File("./resource/test.json").getAbsoluteFile(); Gson gson = new GsonBuilder() .setPrettyPrinting() .create(); User root = gson.fromJson(new FileReader(jsonFile), User.class); System.out.println(root); } }
上面的代码用于下面的JSON有效负载:
JSON
{ "data": [ { "id": "c87ca3fe85781007869b83f" } ] }
印刷品:
User{data=Data{id='c87ca3fe85781007869b83f'}}
而对于object案件JSON的有效载荷:
{ "data": { "id": "c87ca3fe85781007869b83f" } }
如果您的媒体资源可以包含JSON object或multi-elementarray看到我对此问题的回答(将Json数组映射到Java模型)。实现了反序列化程序,可以处理这种情况。
JSON object
multi-elementarray