从API(由Jackson生成)获取大型JSON响应,并且该对象仅在响应的第一次出现时才具有其值。第二次相同对象(具有相同密钥)到达时,将替换为某个数字/ ID。
JSON响应看起来像
[{id:1,Person:{name:"xyz",age:30}},
{id:2,Person:1}]
现在我想通过遵循GSON代码将整个响应存储在列表中
Type listType = new TypeToken<List<MainModel>>() {}.getType();
yourMainList = new Gson().fromJson(myres, listType);
//here myres is whole response and MainModel is my pojo class mapped with JSON response keys
但是当ID /数字重复的密钥第二次到达时,它给了我以下错误。
IllegalStateException:应为BEGIN_OBJECT,但在第1行第11935列的路径$ [1]处为NUMBER。在com.google.gson.stream.JsonReader.beginObject
有什么方法可以在Android中通过GSON解析此类JSON吗?
答案 0 :(得分:0)
您需要确定如何处理Person类的不同变体。这是使用com.google.gson.JsonParser的最简单方法。
private void start() {
String json = "[{id:1,Person:{name:\"xyz\",age:30}},\n" +
"{id:2,Person:1}]";
HashMap<Integer, Person> map = new HashMap<>();
JsonArray items = new JsonParser().parse(json).getAsJsonArray();
items.forEach(jsonElement -> {
JsonObject jsonObject = jsonElement.getAsJsonObject();
int id = jsonObject.get("id").getAsInt();
JsonElement element = jsonObject.get("Person");
if(element.isJsonObject()){
JsonObject personObject = element.getAsJsonObject();
Person person = new Person();
person.name = personObject.get("name").getAsString();
person.age = personObject.get("age").getAsInt();
map.put(id, person);
}
else {
int personValue = element.getAsInt();
map.put(id, new Person(personValue));
}
});
for (int id : map.keySet()) {
Person person = map.get(id);
Log.d("myTag", id + ", name: " + person.name + ", age: " + person.age);
}
}
class Person{
String name;
int age;
Person(){}
Person(int personValue) {
// decide how the object should look
}
}
输出:
1,名字:xyz,年龄:30
2,姓名:null,年龄:0
如果您希望以更通用的方式工作而不必用力键入字段名称,则可以使用Gson Custom Deserialization
答案 1 :(得分:0)
一种选择是对有问题的字段使用自定义JsonDeserializer
,就像这样:
public class PersonDeSerializer implements JsonDeserializer<Person> {
@Override
public Person deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
try {
return context.deserialize(json, typeOfT);
} catch (JsonSyntaxException e) {
// return null to elave null or make whatever kind of a person
return null;
}
}
}
然后您可以设置使用该适配器反序列化的问题字段,例如:
public class MainModel {
private Long id;
@JsonAdapter(PersonDeSerializer.class)
private Person Person; // should be person, but is Person in JSON
}