Почему данные этого JSON файла не сохраняются правильно в Java объектах? - PullRequest
0 голосов
/ 06 февраля 2020

Мне нужно десериализовать следующее JSON:

{
  "locations":
  [
    {
      "name": "Sagrada Família",
      "coordinates": [2.174400, 41.403475],
      "description": "Famosa església inacabada iniciada la dècada de 1880, amb un museu i vistes de la ciutat.",
      "architect": "Antoni Gaudí i Cornet",
      "inauguration": 2026
    },
    {
      "name": "Plaça Catalunya",
      "coordinates": [2.170079, 41.386878],
      "description": "La plaça de Catalunya és la més cèntrica i gran de les places de Barcelona. Constitueix el punt d'unió \nentre el nucli antic de la ciutat i l'Eixample. D'aquí parteixen importants vies de la ciutat com la Rambla, \nel passeig de Gràcia, la rambla de Catalunya, les rondes de la Universitat i de Sant Pere i el carrer Pelai, \nigual com l'avinguda del Portal de l'Àngel, la gran artèria comercial de la ciutat, i antiga porta de \nles muralles."
    },
    {
      "name": "Can Punyetes",
      "coordinates": [2.159704, 41.398694],
      "description": "Restaurant de cuina catalana.",
      "characteristics": ["Acollidor", "Informal", "Està bé per als nens"]
    },
    {
      "name": "Traphouse",
      "coordinates": [2.165150, 41.405290],
      "description": "Casa reconeguda principalment per les cançons que es composen aquí. Els veïns són una delícia, \nmai es queixen del xivarri que hi ha."
    },
    {
      "name": "Lloc de Socis",
      "coordinates": [2.166506, 41.402617],
      "description": "Si alguna vegada vols ser soci d'un club on la gent s'ho passa molt bé, aquest és el lloc \non has d'anar. No te'n penediràs!"
    },
    {
      "name": "Adoquín Square",
      "coordinates": [2.172804, 41.388794],
      "description": "Plaça coneguda pels jocs lúdics que s'organitzen. Es poden fer des de partides de Minecraft fins al \njoc de la manguera d'aigua. També s'ofereix servei de barbacoa."
    },
{
      "name":"Hotel W",
      "coordinates": [2.190109, 41.368762],
      "description": "Hotel més famós de Barcelona definit per la seva forma de vela. A dins t'hi pots trobar de tot\n menys Barcelonins. Ha estat galardonat amb el premi per més mites per metre quadrat de la ciutat, \nprecedit per La Salle Campus Barcelona",
      "stars": 5
    }
  ]
}

Как видите, этот JSON содержит различные объекты из класса Location, но местоположение может быть Hotel , Restaurant или Monument в зависимости от атрибутов каждого местоположения на JSON. Из-за этого я реализовал следующие классы:

public class Location {

    private String name;
    private double[] coordinates;
    private String description;
}

public class Hotel extends Location {

    private short stars;
}

public class Monument extends Location {

    private String architect;
    private short inauguration;
}

public class Restaurant extends Location {

    private String[] characteristics;
}

А также класс с именем DataModel, чтобы сохранить все местоположения из JSON:

public class DataModel {

    private Location[] locations;
}

Я думал выполнение этого кода для загрузки данных в объекты будет правильным:

try {

    reader = new JsonReader(new FileReader(path));
    dataModel = gson.fromJson(reader, DataModel.class);

 } catch(FileNotFoundException e) { System.out.println("Error"); }

Но он просто сохраняет все данные в Location объектах, а не в подобъектах Location, исключая подобъект Переменные.

Как правильно сделать это?

1 Ответ

0 голосов
/ 06 февраля 2020

"Я думал, что gson заметит классы, расширяющие основной класс Location и его атрибуты"

Нет. Используя ссылку на экземпляр звезды, как я упоминал в комментариях, gson видит это так, что вы фактически говорите, что звезды - это экземпляр для локаций. В действительности вы пытаетесь сказать, что у объекта Location есть экземпляр класса Hotel, который содержит звезды.

Взяв пример из здесь - было бы замечательно оформить заказ.

{
  "value1": "value1",
  "value2": "value2",
  "innerClass": {
    "value3": "value3",
    "value4": "value4"
  }
}

Как видите, внешний класс имеет три атрибута: value1, value2 и объект с именем innerClass, который содержит свои собственные экземпляры. Вы говорите десериализатору, что, когда он находится во внешнем классе, нужно искать значения1, значение2 и внутренний класс. Если вы представите его со значением 3 и значением 4, он не будет знать, что с ними делать, потому что о них никогда не было сказано; он знает только о value3 и value4, когда он находится во внутреннем классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...