【问题标题】:JSONException: Issues trying to retrieve data from JSONJSONException:尝试从 JSON 检索数据时出现问题
【发布时间】:2017-06-16 22:34:53
【问题描述】:

好的,所以我正在尝试从 JSON 的列表中提取数据,例如:

{"code":200,"status":"OK","data":{"timings":{"Fajr":"04:17","Sunrise":"05:30","Dhuhr":"12:20","Asr":"15:42","Sunset":"19:11","Maghrib":"19:11","Isha":"20:24","Imsak":"04:07","Midnight":"00:20"},"date":{"readable":"17 Jun 2017","timestamp":"1497652236"}}}

专门针对特定的祈祷。我查找数据的代码如下:

 class SaveTheFeed extends AsyncTask<Void, Void, Void>{
    String jsonString = "";
    String result = "";
    EditText chosenCity = (EditText) findViewById(R.id.editText3);
    String city = chosenCity.getText().toString();

    @Override
    protected Void doInBackground(Void... voids) {
        DefaultHttpClient httpClient = new DefaultHttpClient(new BasicHttpParams());
        HttpPost httpPost = new HttpPost("http://api.aladhan.com/timingsByCity?city=" + city + "&country=AE&method=2");
        httpPost.setHeader("Content-type", "application/json");
        InputStream inputStream;

        try{
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            inputStream = entity.getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
            StringBuilder builder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) !=null){
                builder.append(line + "\n");
            }
            jsonString = builder.toString();

            JSONObject jObject = new JSONObject(jsonString);

            JSONObject data = (JSONObject) jObject.get("data");

            JSONArray jArray = (JSONArray) data.get("timings");

            outputTimings(jArray);

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }
    @Override
    protected void onPostExecute(Void aVoid) {
        TextView prayerTimes = (TextView) findViewById(R.id.prayerTimes);
        prayerTimes.setText(result);
    }

    protected void outputTimings(JSONArray jsonArray){
        String[] prayers= {"Fajr", "Sunrise", "Dhuhr", "Asr", "Sunset", "Maghrib", "Isha", "Imsak", "Midnight"};
        try{
            for(int i = 0; i < jsonArray.length(); i++){
                JSONObject cityObject =
                        jsonArray.getJSONObject(i);
                result = result +  prayers[i] + " : "+
                         cityObject.getString(prayers[i]) + "\n";
            }

我收到指向第 85 行的错误(JSONObject jObject = new JSONObject(jsonString); 行)

06-17 00:24:15.973 2866-2907/azanmute.android.com.azanmute W/System.err: org.json.JSONException: java.lang.String 类型的值无法转换为 JSONObject 06-17 00:24:15.973 2866-2907/azanmute.android.com.azanmute W/System.err: 在 org.json.JSON.typeMismatch(JSON.java:111) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: 在 org.json.JSONObject.(JSONObject.java:160) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: 在 org.json.JSONObject.(JSONObject.java:173) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: 在 azanmute.android.com.azanmute.MainActivity$SaveTheFeed.doInBackground(MainActivity.java:85) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: 在 azanmute.android.com.azanmute.MainActivity$SaveTheFeed.doInBackground(MainActivity.java:60) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: 在 android.os.AsyncTask$2.call(AsyncTask.java:305) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: 在 java.util.concurrent.FutureTask.run(FutureTask.java:237) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: 在 android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 06-17 00:24:15.974 2866-2907/azanmute.android.com.azanmute W/System.err: at java.lang.Thread.run(Thread.java:761)

所以我的理解是我错误地指向数据或将 JSONObjects 与 JSONArrays 混合在一起。我已经尝试过thisthis,但仍然收到相同的错误。

【问题讨论】:

  • 从异常中,我想说问题是您的 String jsonString 不是有效的 JSON 字符串。你能在这里调试一下,并在 l 之前提供 jsonString 的确切值吗? 85?
  • 只需打印您在 HTTP 响应中获得的内容,以确保 URL 向您发送有效的 json 响应
  • MainActivity.java 的第 85 行是哪一行?将事物简化为minimal reproducible example总是很有用 - 目前您的问题中有很多不相关的代码。
  • 除此之外,timings 不是数组——它是另一个对象...
  • 您在顶部的json字符串是正确的,但是错误日志说它不正确。然后我们用调试器打印出new JSONObject(jsonString);之前的jsonString来查看

标签: java android json


【解决方案1】:

在这种情况下,您没有混淆 JSON 对象和 JSON 数组。这绝对是一个 JSONObject。

您可能在字符串中添加了 JSONObject 构造函数不喜欢的“不可见”字符(即“\n”)。试试这个:

JSONObject jObject = new JSONObject(jsonString.substring(jsonString.indexOf("{"), jsonString.lastIndexOf("}") + 1));

另外请注意,“计时”也是一个 JSONObject 而不是 JSONArray。 JSONArray 示例,其中“cars”是 JSONArray:

{"name":"John","age":30,"cars":[ "Ford", "BMW", "Fiat" ]}

【讨论】:

  • 我继续尝试添加您的线路。它仍然出错,但这次是不同的错误:org.json.JSONException: Unterminated object at character 84 of { padding:30px; font:12px/1.5 Helvetica,Arial,Verdana,sans-serif; } h1{ margin:0; font-weight:normal; line-height:48px; } 问题仍然在同一行
  • @Fencer300 您能否发布错误以供我们参考?编辑:谢谢
  • @Fencer300 您的 HTTP 请求没有返回有效的 JSON,而是返回了 HTML 页面内容。
  • 哈哈把我搞砸了。 This 正是我所要求的。我哪里做错了?
  • 在此处查看 JSONObject 的文档:stleary.github.io/JSON-java/org/json/… 几乎可以肯定,您的 JSON 存在问题。尝试打印/记录返回到 jsonString 中的任何内容并将其粘贴到 jsonlint.com 之类的工具中以检查它是否有效。
猜你喜欢
  • 2023-03-17
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
  • 1970-01-01
  • 2021-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多