Как заполнить существующий рекурсивный объект с помощью Gson

#java #json #gson

#java #json #gson

Вопрос:

Я хочу десериализовать строку json внутри существующего объекта. Я написал создатель экземпляра и работает хорошо. Но если объект имеет подобъект с той же структурой (родительский) Я получаю неожиданный результат, потому что Gson десериализует родительский элемент внутри дочернего элемента. Приведенный ниже код выводит:

 Bart 10 Person@6aa5c9f1
Homer 36 Person@6aa5c9f1
Homer 36 Person@6aa5c9f1
  

Но я ожидал:

 Bart 10 Person@6aa5c9f1
Bart 20 Person@6aa5c9f1
Homer 36 Person@6aa5c9f1
  

Спасибо

 public class Test {

    public static void main(String[] args) {

        Person son = new Person();
        son.name = "Bart";
        son.age = 10;

        System.out.println(son.name   " "   son.age   " "   son);

        GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapter(Person.class, new CustomInstanceCreator(son));
        Gson gson = builder.create();

        String json = "{"age":20,"parent":{"name":"Homer","age":36}}";

        son = gson.fromJson(json, Person.class);

        System.out.println(son.name   " "   son.age   " "   son);

        System.out.println(son.parent.name   " "   son.parent.age   " "   son.parent);
    }
}


class Person {

    public String name;
    public int age;
    public Person parent;
}


class CustomInstanceCreator implements InstanceCreator<Person> {

    private Person person;

    public CustomInstanceCreator (Person person) {

        this.person = person;
    }

    public Person createInstance (Type type) {

        return person;
    }
}
  

Комментарии:

1. Очевидно, что адрес son.parent должен отличаться от адреса son

Ответ №1:

Я нашел решение с помощью этого обходного пути

 class CustomInstanceCreator implements InstanceCreator<Person> {

    private Person person;
    private boolean newInstance;

    public CustomInstanceCreator(Person person) {

        this.person = person;
        this.newInstance = false;
    }

    public Person createInstance(Type type) {

        Person instance = person;

        if (newInstance)
            instance = new Person();

        newInstance = true;

        return instance;
    }
}
  

Ответ №2:

Вместо использования Gson я использовал только json. Используемая библиотека json-simple-1.1.jar

 public class JsonApiClass {

    public static void main(String[] args) {
        // TODO Auto-generated method stub


        try {

    String Response = "{"Object1":{"Name1":"Bart","age1":"10"}"
                 "n"  ""Object2":{"Name2":"Bart","age2":"20"}"
                 "n"  ""Object3":{"Name3":"Homer","age3":"36"    }}";




            JSONParser parser = new JSONParser();

            try {

                Object obj = parser.parse(Response);

                JSONObject jsonObject = (JSONObject) obj;

                JSONObject jsonObject1  = (JSONObject)jsonObject.get("Object1");
                JSONObject jsonObject2  = (JSONObject)jsonObject.get("Object2");
                JSONObject jsonObject3  = (JSONObject)jsonObject.get("Object3");


                String name1 = (String)jsonObject1.get("Name1");
                String name2 = (String)jsonObject2.get("Name2");
                String name3 = (String)jsonObject3.get("Name3");

                Long age1 = new Long((String)jsonObject1.get("age1"));
                Long age2 = new Long((String)jsonObject2.get("age2"));
                Long age3 = new Long((String)jsonObject3.get("age3"));


            System.out.println(name1 " " age1);
            System.out.println(name2 " " age2);
            System.out.println(name3 " " age3);




            } catch (Exception e) {
                e.printStackTrace();
            }



        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }

    }
  

ВЫВОД

 Bart 10
Bart 20
Homer 36
  

Надеюсь, это решит вашу проблему

Комментарии:

1. Это был только пример, моя строка json изменяется динамически

2. @user2572547 если вы получаете динамические значения, вы можете использовать метод получения компонента и встроить его в строку json в приведенном выше коде

3. У меня есть вложенный json, и мне нужно десериализовать его внутри существующего объекта