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