为了账号安全,请及时绑定邮箱和手机立即绑定

在json中找到具有不同类型值的相同键时,gson解析错误

在json中找到具有不同类型值的相同键时,gson解析错误

阿晨1998 2021-12-01 17:08:12
从 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/number 的重复键第二次到达响应时,它给了我以下错误。IllegalStateException:应为 BEGIN_OBJECT,但在第 1 行第 11935 列路径 $[1] 处为 NUMBER。在 com.google.gson.stream.JsonReader.beginObject有没有办法在android中通过GSON解析这样的JSON?
查看完整描述

2 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

一种选择是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

}


查看完整回答
反对 回复 2021-12-01
?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

您需要决定如何处理 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、姓名:空、年龄:0


如果您喜欢以更通用的方式工作而不用硬输入您的字段名称,您可以使用Gson 自定义反序列化


查看完整回答
反对 回复 2021-12-01
  • 2 回答
  • 0 关注
  • 239 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信