IllegalStateException when using GSON

advertisements

im trying to read the following JSON file:

{ "rss" : {
     "@attributes" : {"version" : "2.0" },
      "channel" : {
          "description" : "Channel Description",
          "image" : {
              "link" : "imglink",
              "title" : "imgtitle",
              "url" : "imgurl"
            },

          "item" : {
              "dc_format" : "text",
              "dc_identifier" : "link",
              "dc_language" : "en-gb",
              "description" : "Description Here",
              "guid" : "link2",
              "link" : "link3",
              "pubDate" : "today",
              "title" : "Title Here"
            },

          "link" : "channel link",
          "title" : "channel title"
        }
    }
}

Into this object:

public class RSSWrapper{
    public RSS rss;

    public class RSS{
        public Channel channel;
    }

    public class Channel{
        public List<Item> item;

    }
    public class Item{
        String description;//Main Content
        String dc_identifier;//Link
        String pubDate;
        String title;

    }
}

Im only interested in knowing what's in the "item" object so i assumed the above class would work when calling:

Gson gson = new Gson();
RSSWrapper wrapper = gson.fromJson(JSON_STRING, RSSWrapper.class);

but im getting an error:

Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT

I don't really know what this means so I don't know where to look for the error, hopefully someone with a better knowledge of GSON can help me?

Thanks :)


If you control how the JSON input looks like, you're better off changing item to a JSON array

"item" : [{
    "dc_format" : "text",
    "dc_identifier" : "link",
    "dc_language" : "en-gb",
    "description" : "Description Here",
    "guid" : "link2",
    "link" : "link3",
    "pubDate" : "today",
    "title" : "Title Here"
}]

If you do not and want your program to be able to handle both item array or object with the same RSSWrapper class; here's a programmatic solution for you.

JSONObject jsonRoot = new JSONObject(JSON_STRING);
JSONObject channel = jsonRoot.getJSONObject("rss").getJSONObject("channel");

System.out.println(channel);
if (channel.optJSONArray("item") == null) {
    channel.put("item", new JSONArray().put(channel.getJSONObject("item")));
    System.out.println(channel);
}

Gson gson = new Gson();
RSSWrapper wrapper = gson.fromJson(jsonRoot.toString(), RSSWrapper.class);

System.out.println(wrapper.rss.channel.item.get(0).title); // Title Here

Using the Java org.json parser, the code simply replaces the JSONObject by wrapping it into an array. It leaves the JSON_STRING untouched if item is already a JSONArray.