1

我在解析 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;

}

}

堆栈跟踪的一部分:

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 文件的 URL 是“ http://witnesskingtides.azurewebsites.net/api/kingtides

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

我的问题是为什么会出现 JASON 异常以及如何解决它。

4

5 回答 5

3

您得到的响应是 XML 响应,您正试图将其解析为 JSON。请参阅有关 XML 解析的本教程

于 2014-03-14T05:00:02.197 回答
1

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

不过,我不知道您的实际问题的答案,因为 JSON 似乎在我尝试过的所有事情中都得到了验证。也许与Android解析器不兼容?

我建议在您的 Android 应用程序中尝试使用不同的解析器来解析来自服务器的响应。我之前使用过 Gson,它易于设置和使用。

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

于 2014-03-14T13:37:14.743 回答
1

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

JSONObject jsonObj = new JSONObject(jsonStr);

采用

JSONArray jsonArray = new JSONArray(jsonStr);

并从那里继续。

于 2014-03-14T13:56:51.227 回答
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”的数组属性的对象)。

于 2014-03-14T14:00:25.463 回答
0

更新:忽略我下面的回答......

不要打破你重复的关于它是 JSON 的概念,它不是。

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

然而,

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

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

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

我不确定ServiceHandler该类是如何工作的,但是当您创建请求时,您应该添加带有名称和值GET的 HTTP 标头,然后发出请求。您现在将返回 JSON 而不是 XML。Acceptapplication/json

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

于 2014-03-14T13:39:20.513 回答