简体   繁体   中英

GSON deserialization: nested JSon file error

I am trying to parse JSon File and I cannot figure my mistake (smaller examples work flawlessly)

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: (is rather long) http://pastebin.com/uaEY7dty

When I do as usualy:

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

It crashes... I am stuck on it for several days and cannot get it right.

BTW: it is my first question on SO, so please excuse me if it is not presented as it should be.

EDIT:

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)

EDIT 2:

1) Song is now static 2) Lyrics are inside List (there are more sections inside)

EDIT 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 ...

But it still doesn't work ... Am I missing something else ?

You have a problem with Lyrics field, Gson expects an object but you provide an array (with an object only).

This is your your class:

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

and this is your unmatched part of JSON

 "lyrics": [
      //more things here      
  ]

As you can see, with square bracket, a new array begins.

To solve, change lyrics field to List<Lyrics> if you want to parse it as is, otherwise change your JSON, if you can, removing square brackets. Of course you have to change also getter and setter for lyric field. In code terms, change like this:

 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;}
 }

This is my execution:

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

with this result:

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

There are a couple of issues here.

  1. Lyrics is an array in the JSON file, but your variable is not. Change it to List<Lyrics>
  2. The inner class Song is not static, which can be an issue (although apparently this is working for you): see here why .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM