JSON异常问题 - Android

时间:2014-03-14 04:57:30

标签: android android-json

在解析我的JSON对象时,我无法弄清楚为什么我会收到JSON异常。我从URL获取(Http GET)JASON。以下是所有相关代码,如果您需要查看更多代码,请告诉我

doInBackground异步方法:

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

服务处理程序类:

    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;

}

}

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 

JASON文件的网址是&#34; http://witnesskingtides.azurewebsites.net/api/kingtides&#34;

注意:我知道它看起来像一个XML文件,但它是JASON。只需通过验证器/查看器运行它,如果需要,可以查看自己。

我的问题是为什么我会收到JASON异常以及如何修复它。

5 个答案:

答案 0 :(得分:3)

您获得的响应是​​XML响应,您尝试将其解析为JSON。 请参阅有关XML解析的this tutorial

答案 1 :(得分:1)

确认该服务实际上是返回JSON响应(您可以在像Fiddler这样的工具中检查)。 API的默认响应是JSON。您通过单击问题中提供的链接看到XML的原因是因为浏览器正在请求application / xml的内容类型,因此浏览器将接收该内容。

我不知道你的实际问题的答案,因为JSON似乎验证了我所尝试过的一切。可能与Android解析器不兼容?

我建议您在Android应用中尝试使用不同的解析器来解析服务器的响应。我之前使用过Gson很容易设置和使用。

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

答案 2 :(得分:1)

该服务返回一个对象数组,而不是

JSONObject jsonObj = new JSONObject(jsonStr);

使用

JSONArray jsonArray = new JSONArray(jsonStr);

并从那里继续。

答案 3 :(得分:1)

获取内容时,我得到了回复(部分内容):

[
    {
        "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
    },
    ...
]

这意味着您的对象已经是一个数组。尝试在代码中更改此内容:

                //JSONObject jsonObj = new JSONObject(jsonStr);

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

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

因为返回的jsonStr已经是一个数组(而不是一个名为“JASON”的数组属性的对象)。

答案 4 :(得分:0)

更新:忽略我的答案......

不要破坏你重复的关于它是JSON的事实,它不是。

您的代码返回的响应是纯XML。

然而,

您请求的资源(http://witnesskingtides.azurewebsites.net/api/kingtides)支持XML格式的响应和JSON格式的响应。这可能与您的代码中的请求中缺少的Accept标头有关,或者在application/xml中设置为text/xmlServiceHandler或类似内容。

当您的代码获得服务器的响应时,服务器找不到Accept标头并返回XML格式。

当你提到的JSON验证器站点请求相同的URL时,它们可能会添加一个Accept标头,告诉服务器以JSON格式返回响应。

我不确定ServiceHandler类是如何工作的,但是当您创建GET请求时,您应该添加名称为Accept且值为application/json的HTTP标头,并且然后发出请求。您现在将获得JSON而不是XML。

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