在这一点上,这已经是一个老问题了,我可能已经阅读了SO上的每个相关主题。
但是要点。我需要一些建议或更正吗?
由于某种原因,我们产生了两种类型的可生成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;
}
}
Baseppi类中的Gson生成器,以防万一:
Gson gson = new GsonBuilder().registerTypeAdapter(UserDeserializer.class, new UserDeserializer()).setLenient().create();
没有自定义反序列化和数组JSON问题,它将可以完美地工作。但是现在我必须确定我得到的“数据”的确切类型。
在上述情况下,我得到java.lang.ClassCastException: java.util.ArrayList cannot be cast to auto.Rest.Data
我假设我必须创建另一个 Data 类(例如将有 DataObject 和 DataArray ),并像我一样描述每个参数之前在 Data.class 中获得此工作?我想反序列化期间做错了什么,但是我不确定tbh在哪里。
还是我错了,可以将 Data 用作 List ,将 Data 用作 Object 同一班?
我已经为此工作了好几天(?),并且正在考虑使用泛型而不是Gson帮助,是的,我很绝望。因此,任何帮助表示赞赏。
答案 0 :(得分:0)
如果总是有一个对象,只需添加
json.getAsJsonArray()。get(0);
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().get(0);
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;
}
}
如果有更多对象,请将字段数据更改为列表
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();
List<Data> data = new ArrayList<Data>();
data.add(context.deserialize(jsonElement, Data.class)) ;
user.data = data ;
// user.setData(new Gson().fromJson(jsonElement, new TypeToken<Data>() {}.getType()));
}
return user;
}
}
并将User.class字段数据更改为List
public List<Data> data;
这与科特林语link
类似。答案 1 :(得分:0)
如果您总是有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
有效负载的代码:
{
"data": [
{
"id": "c87ca3fe85781007869b83f"
}
]
}
打印:
User{data=Data{id='c87ca3fe85781007869b83f'}}
对于object
情况下的JSON
有效载荷:
{
"data": {
"id": "c87ca3fe85781007869b83f"
}
}
打印:
User{data=Data{id='c87ca3fe85781007869b83f'}}
如果您的财产可能包含JSON object
或multi-element array
,请参阅我对问题Mapping Json Array to Java Models的回答。实现了反序列化程序,可以处理这种情况。