androidjsonjsonreader

JsonReader throwing IllegalStateException


I found out that using http://ip-api.com/json is an easy way of getting the the necessary user location details. The result, for example from the site is:

{"as":"AS37061 ONECOM","city":"Nairobi","country":"Kenya","countryCode":"KE","isp":"One Communications Ltd","lat":-1.2833,"lon":36.8167,"org":"ONECOM","query":"41.203.219.198","region":"110","regionName":"Nairobi Province","status":"success","timezone":"Africa/Nairobi","zip":""}

I have been parsing the above Json result with the following code:

String countryCode = null;
    String name = null;

    if (reader != null) {
        try {
            reader.setLenient(true);

            reader.beginObject();

            while (reader.hasNext()) {
                switch (reader.nextName()) {
                    case "countryCode":
                        countryCode = reader.nextString().toLowerCase();
                        break;
                    case "country":
                        name = reader.nextString();
                        break;
                    default:
                        reader.skipValue();
                        break;
                }
            }

            reader.endObject();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Now I am getting this error:

Fatal Exception: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was END_DOCUMENT at line 1 column 2016
   at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:374)
   at com.radioafrica.music.fragment.TopTracks.getCountryCode(TopTracks.java:397)
   at com.radioafrica.music.fragment.TopTracks.access$1100(TopTracks.java:57)
   at com.radioafrica.music.fragment.TopTracks$9.run(TopTracks.java:377)
   at java.lang.Thread.run(Thread.java:818)

As far as I can tell, the code is fine, but it isn't always working. What seems to be the problem?


Solution

  • I think there are two problems: you forgot something in your code, and the way you are parsing JSON:

    1. Your code does not seem to be checking that if reader contains an empty String. (It can happen when IP-API returns bad answer or just nothing).
    2. Bonus point: you should not handle this low-level problem by yourself. Actually, a lot of very light and extremely reliable libraries will do the JSON parsing for you. It will handle this kind of problem and give you clear exception. You can try Gson or anything else that fits your needs better.