Question

I am having trouble figuring out why i'm getting a JSON exception while I am parsing my JSON object. I am getting(Http GET) the JASON from a URL. Here is all the relevant code, let me know if you need to see any more of the code

The doInBackground Async method:

@Override
    protected Void doInBackground(Void... arg0) 
    {
        // Creating service handler class instance
        ServiceHandler sh = new ServiceHandler();

        // Making a request to url and getting response
        String jsonStr = sh.makeServiceCall(URL,ServiceHandler.GET);

        Log.w("Rakshak", "the jaon String is:"+jsonStr);// this prints the JASON in the log and it looks fine
                                                        // I am not pasting it in coz it is HUGE 

        if (jsonStr != null)
        {
            try {
                    JSONObject jsonObj = new JSONObject(jsonStr);

                    Log.w("Rakshak", "in the try before the JASON");

                    // Getting JSON Array node
                    kingtide = jsonObj.getJSONArray("JASON");

                    // looping through All Kingtide events
                    for (int i = 0; i < kingtide.length(); i++) 
                    {
                        JSONObject k = kingtide.getJSONObject(i);

                        String date = "Date Range:"+k.getString(KEY_DATE);
                        String lat = k.getString(KEY_LAT);
                        String lng = k.getString(KEY_LNG);
                        String loc = "Location of the Kingtide:"+k.getString(KEY_LOC)+", "+k.getString(KEY_STATE);
                        String temp_Time = k.getString(KEY_TIME);
                        String[] time_parts = temp_Time.split("T");
                        String time = "Kingtide at:"+time_parts[1]+" "+getYear(time_parts[0]);

                        // tmp hashmap for single kingtide event
                        HashMap<String, String> kt = new HashMap<String, String>();

                        // adding each child node to HashMap key => value
                        kt.put(KEY_DATE, date);
                        kt.put(KEY_LAT, lat);
                        kt.put(KEY_LNG, lng);
                        kt.put(KEY_LOC, loc);
                        kt.put(KEY_TIME, time);

                        Log.w("Rakshak", KEY_DATE+KEY_LAT+KEY_LNG+KEY_LOC+KEY_TIME);

                        // adding the kingtide to the kingtide hash map. this will be used to fill up the list view
                        kingTideList.add(kt);
                    }

                } catch (JSONException e) {
                    Log.e("Rakshak", "JSONException "+e.getMessage());  // this prints "JSONException Value [{"Latitude":-19.9078861,"Location":"Abbot....." and the rest of the JASON(all of it) 
                }
        }
        else 

            Log.w("Rakshak", "JASON string is null"); 

        return null;
    }

the Service handler class:

    public class ServiceHandler {

static String response = null;
public final static int GET = 1;
public final static int POST = 2;

public ServiceHandler() {

}

/*
 * Making service call
 * @url - url to make request
 * @method - http request method
 * */
public String makeServiceCall(String url, int method) {
    return this.makeServiceCall(url, method, null);
}

/*
 * Making service call
 * @url - url to make request
 * @method - http request method
 * @params - http request params
 * */
public String makeServiceCall(String url, int method,
        List<NameValuePair> params) {
    try {
        // http client
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpEntity httpEntity = null;
        HttpResponse httpResponse = null;

        // Checking http request method type
        if (method == POST) {
            HttpPost httpPost = new HttpPost(url);
            // adding post params
            if (params != null) {
                httpPost.setEntity(new UrlEncodedFormEntity(params));
            }

            httpResponse = httpClient.execute(httpPost);

        } else if (method == GET) {
            // appending params to url
            if (params != null) {
                String paramString = URLEncodedUtils
                        .format(params, "utf-8");
                url += "?" + paramString;
            }
            HttpGet httpGet = new HttpGet(url);

            httpResponse = httpClient.execute(httpGet);

        }
        httpEntity = httpResponse.getEntity();
        response = EntityUtils.toString(httpEntity);

    } catch (UnsupportedEncodingException e) {
        Log.e("Rakshak", "UnsupportedEncodingException "+e.getMessage());
    } catch (ClientProtocolException e) {
        Log.e("Rakshak", "ClientProtocolException "+e.getMessage());
    } catch (IOException e) {
        Log.e("Rakshak", "IOException "+e.getMessage());
    }


    Log.w("Rakshak", "In the service handeler: this is a test");


    return response;

}

}

Part of the stacktrace:

03-14 10:09:56.861: E/Rakshak(7037): JSONException Value [{"Latitude":-19.9078861,"Location":"Abbot Point","Longitude":148.08467259999998,"DateRange":"1–3 January 2014","HighTideOccurs":"2014-01-02T09:47:00","State":"QLD"},{"Latitude":-27.477819,"Location":"Brisbane 

The URL for the JASON file is "http://witnesskingtides.azurewebsites.net/api/kingtides"

NOTE: I know it looks like a XML file but it is JASON . Just run it through a validator/viewer and see for your self if you want.

My question in why am I getting a JASON exception and how do I fix it.

Was it helpful?

Solution 2

When getting the contents, I get this back (part of it):

[
    {
        "Location": "Abbot Point",
        "State": "QLD",
        "HighTideOccurs": "2014-01-02T09:47:00",
        "DateRange": "1–3 January 2014",
        "Latitude": -19.9078861,
        "Longitude": 148.08467259999998
    },
    {
        "Location": "Brisbane  Bar",
        "State": "QLD",
        "HighTideOccurs": "2014-01-02T10:16:00",
        "DateRange": "1–3 January 2014",
        "Latitude": -27.477819,
        "Longitude": 153.01889119999998
    },
    ...
]

This means that your object is already an array. Try to change this in your code:

                //JSONObject jsonObj = new JSONObject(jsonStr);

                Log.w("Rakshak", "in the try before the JASON");

                // Getting JSON Array node
                kingtide = new JSONArray(jsonStr);

since the returned jsonStr is already an array (and not an object with an array-attribute called "JASON").

OTHER TIPS

The Response you are getting is XML response and you are trying to parse it as JSON. Refer this tutorial on XML parsing

Confirmed that the service is in fact returning a JSON response (you can check this in a tool like Fiddler). The default response from the API is JSON. The reason you are seeing XML by clicking the link provided in the question is because the browser is requesting a content type of application/xml, so that is what the browser shall receive.

I don't know the answer to your actual problem though, as the JSON seems to validate in everything I've tried. Maybe an incompatibility with the Android parser?

I'd suggest trying a different parser in your Android app to parse the response from the server. I've used Gson before which was easy to set up and use.

http://www.javacodegeeks.com/2011/01/android-json-parsing-gson-tutorial.html

The service returns an array of objects so instead of

JSONObject jsonObj = new JSONObject(jsonStr);

use

JSONArray jsonArray = new JSONArray(jsonStr);

and continue from there.

Update: Disregard my answer below...

Not to burst your repeated notion of the fact that it is JSON, it is not.

The response that your code gets back is plain XML.

However,

The resource you are requesting ( http://witnesskingtides.azurewebsites.net/api/kingtides ) supports both XML formatted responses and JSON formatted responses. It probably all has to do with the Accept headers that are missing from your request in your code or are set to application/xml or text/xml or something similar in your ServiceHandler.

When your code gets the response of the server, the server does not find an Accept header and returns XML format.

When the JSON validator sites, that you mention, request the same URL, they likely add an Accept header that tells the server to return the response in JSON format.

I'm not sure how the ServiceHandler class works, but when you create a GET request you should add the HTTP Header with name Accept and value application/json and then issue the request. You now will get JSON back instead of XML.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top