Volley解析JSON报错:JSONArray无法转为JSONObject求助
解决Volley请求JSON时的类型转换异常问题
嘿,我来帮你搞定这个问题!你遇到的org.json.JSONException完全是因为API返回了两种不同格式的JSON响应,而你的代码只处理了其中一种情况:
问题根源
你用了JsonObjectRequest来发起请求,但这个请求类只能处理根节点是JSONObject的响应。当API直接返回JSON数组时,Volley会尝试把数组转换成JSONObject,这就触发了类型转换异常。
解决方案:用StringRequest兼容两种格式
我们可以先把响应以字符串形式获取,再手动判断它是JSON数组还是JSONObject,分别处理两种情况。这样就能同时兼容你提到的两种API返回格式了。
替换你原来的JsonObjectRequest代码,改成下面这样:
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { try { // 用JSONTokener判断响应类型 Object json = new JSONTokener(response).nextValue(); mExampleList.clear(); // 先清空列表,避免重复添加 if (json instanceof JSONArray) { // 处理直接返回JSON数组的情况 JSONArray jsonArray = (JSONArray) json; Log.d("1", "onResponse: 处理JSON数组格式"); for (int i = 0; i < jsonArray.length(); i++) { JSONObject hit = jsonArray.getJSONObject(i); addArticleToList(hit); } } else if (json instanceof JSONObject) { // 处理包含articles对象的JSONObject情况 JSONObject responseObj = (JSONObject) json; JSONObject articlesObj = responseObj.getJSONObject("articles"); Log.d("1", "onResponse: 处理articles对象格式"); // 遍历articles里的所有键值对 Iterator<String> keys = articlesObj.keys(); while (keys.hasNext()) { String key = keys.next(); JSONObject hit = articlesObj.getJSONObject(key); addArticleToList(hit); } } // 更新适配器 mExampleAdapter = new ExampleAdapter(MainActivity.this, mExampleList); mRecyclerView.setAdapter(mExampleAdapter); mExampleAdapter.notifyDataSetChanged(); // 确保数据刷新 } catch (JSONException e) { e.printStackTrace(); Log.d("1", "onResponse: 解析JSON出错"); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.d("1", "onErrorResponse: Error response"); error.printStackTrace(); } }); mRequestQueue.add(request);
然后添加一个复用的方法来提取文章数据(避免重复代码):
private void addArticleToList(JSONObject hit) throws JSONException { // 注意:第二个JSON里有个拼写错误"locatoin",如果API实际返回是这个,要改成对应的key String title = hit.getString("title"); String imageUrl = hit.getString("imageURL"); String article = hit.getString("content"); String author = hit.getString("author"); String date = hit.getString("time"); mExampleList.add(new ExampleItem(imageUrl, title, article, author, date)); Log.d("1", "添加了一篇文章: " + title); }
额外提醒
- 注意你提供的第二个JSON里有个字段拼写错误:
locatoin(正确应该是location),如果API实际返回就是这个错误拼写,提取的时候要对应上,否则会抛出字段找不到的异常。 - 每次解析前清空列表
mExampleList.clear(),避免多次请求时数据重复累积。
这样修改后,你的代码就能同时处理两种不同的JSON响应格式,不会再出现类型转换的异常啦!
内容的提问来源于stack exchange,提问作者adarsh keshri
相关产品推荐
相关产品推荐

