Десериализация GSON: ошибка вложенного файла JSon

Я пытаюсь разобрать файл JSon и не могу понять свою ошибку (меньшие примеры работают без нареканий)

Song.json

{
    "song": {
        "fileInfo": {
            "version": "0.1",
            "createdIn": "PickWorks Studio",
            "modifiedIn": "PickWorks Studio",
            "modified": "2010-01-28T13:15:30+01:00"
        },
        "properties": {
            "authors": [
                {
                    "name": "Juri Traktori",
                    "type": "music",
                    "lang": "en"
                }
            ],
            "titles": [
                {
                    "title": "Rainy day",
                    "lang": "en",
                    "original": true
                },
                {
                    "title": "Descowe dni",
                    "lang": "pl"
                }
            ],
            "copywright": "Michal Tomanek",
            "released": "19-03-1993",
            "transposition": -3,
            "tempo": {
                "type": "text/bpm",
                "value": "moderate/90"
            },
            "key": "A",
            "version": 0.99,
            "publisher": "myself",
            "keywords": [ "grace", "words","amazing"],
            "verseOrder": "v1 v2 v1 v1 v2",
            "themes": [
                {
                    "theme": "adoration"
                }
            ]
        },
        "lyrics": [
            {
                "section": "v1",
                "lines": [
                    {
                        "lang": "en",
                        "part": "man",
                        "text": "How <chord name=\"A\"/>great is <br/>your love",
                        "comment": "Sing softly"
                    },
                    {
                        "lang": "en",
                        "part": "woman",
                        "text": "How great is your love to us"
                    }
                ]
            }
        ]
    }
}

SongType.java: (довольно длинный) http://pastebin.com/uaEY7dty

Когда я делаю как обычно:

Gson gson = new Gson() ;
SongType parsed = gson.fromJson(json, SongType.class);

Он падает... Я застрял на нем в течение нескольких дней и не могу сделать это правильно.

Кстати: это мой первый вопрос по SO, поэтому, пожалуйста, извините, если он не представлен так, как должно быть.

РЕДАКТИРОВАТЬ:

Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 692
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
    at com.google.gson.Gson.fromJson(Gson.java:803)
    at com.google.gson.Gson.fromJson(Gson.java:768)
    at com.google.gson.Gson.fromJson(Gson.java:717)
    at com.google.gson.Gson.fromJson(Gson.java:689)
    at Main.main(Main.java:14)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 692
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:374)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:165)

РЕДАКТИРОВАТЬ 2:

1) Песня теперь статична. 2) Тексты песен находятся внутри списка (в нем больше разделов).

РЕДАКТИРОВАТЬ 3:

import java.util.List;

public class SongType {
    public static Song song;

    public class Song {
        public FileInfo     fileInfo;
        public Properties   properties;
        public List<Lyrics> lyrics;

        public FileInfo getFileInfo()     {return fileInfo;}
        public Properties getProperties() {return properties;}
        public List<Lyrics> getLyrics()   {return lyrics;}

        public void setFileInfo(FileInfo fileInfo)       {this.fileInfo   = fileInfo;}
        public void setProperties(Properties properties) {this.properties = properties;}
        public void setLyrics(List<Lyrics> lyrics)       {this.lyrics     = lyrics;}
    } 
//code continues here ...

Но это все еще не работает... Я что-то упустил?

2 ответа

Решение

У вас проблемы с Lyrics поле, Gson ожидает объект, но вы предоставляете массив (только с объектом).

Это твой класс:

 public class Song {
                public FileInfo   fileInfo;
                public Properties properties;
                public Lyrics    lyrics;
                // more rows

и это ваша непревзойденная часть JSON

 "lyrics": [
      //more things here      
  ]

Как видите, с квадратной скобкой начинается новый массив.

Чтобы решить, изменить lyrics поле для List<Lyrics> если вы хотите разобрать его как есть, измените JSON, если можете, удалив квадратные скобки. Конечно, вы должны изменить также геттер и сеттер для lyric поле. В терминах кода измените это так:

 public static class Song {
      public FileInfo   fileInfo;
      public Properties properties;
      public List<Lyrics>    lyrics;

      public FileInfo getFileInfo()     {return fileInfo;}
      public Properties getProperties() {return properties;}
      public List<Lyrics> getLyrics()                 {return lyrics;}

      public void setFileInfo(FileInfo fileInfo)               {this.fileInfo   = fileInfo;}
      public void setProperties(Properties properties) {this.properties = properties;}
      public void setLyrics(List<Lyrics> lyrics)                     {this.lyrics     = lyrics;}
 }

Это мое исполнение:

    Gson gson = new Gson() ;
    SongType parsed = gson.fromJson(s, SongType.class);
    System.out.print(parsed.song.getLyrics().get(0).getLines().get(0).getText());

с этим результатом:

How <chord name="A"/>great is <br/>your love

Здесь есть пара вопросов.

  1. Тексты песен - это массив в файле JSON, а ваша переменная - нет. Измените это на List<Lyrics>
  2. Внутренний класс Song не является статичным, что может быть проблемой (хотя, очевидно, это работает для вас): посмотрите здесь, почему.
Другие вопросы по тегам