Android端报JSONException: JSONObject无法转换为JSONArray问题
问题描述
通过IP地址访问Web服务接口时,Android端抛出JSON类型不匹配异常,同接口在浏览器中访问可返回正常响应,异常日志如下:
org.json.JSONException: Value {"dsdata":{"ttlogin":[{"BundyId":"9090","Name":"IT DEVELOPMENT"}]}} of type org.json.JSONObject cannot be converted to JSONArray W/System.err: at org.json.JSON.typeMismatch(JSON.java:112)
原有业务代码
@Override protected String doInBackground(String... params) { String login_url ="http://200.200.200.20/bin/dev/dispatch/truckunloading.p"; try { URL url = new URL(login_url); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setConnectTimeout(10000); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setDoOutput(true); httpURLConnection.setDoInput(true); OutputStream OS = httpURLConnection.getOutputStream(); BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(OS, "UTF-8")); String data = URLEncoder.encode("ctype", "UTF-8") + "=" + URLEncoder.encode("login", "UTF-8") + "&" + URLEncoder.encode("clogin", "UTF-8") + "=" + URLEncoder.encode("9090", "UTF-8"); bufferedWriter.write(data); bufferedWriter.flush(); bufferedWriter.close(); OS.close(); Log.e("ERROR OBJECT", "Conneting"); InputStream inputStream = httpURLConnection.getInputStream(); BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream, "iso-8859-1")); String response = ""; String line = ""; while ((line = bufferedReader.readLine()) != null) { response += line; } bufferedReader.close(); inputStream.close(); httpURLConnection.disconnect(); try { JSONArray jsonarray = new JSONArray(response); for (int i = 0; i < jsonarray.length(); i++) { JSONObject jsonobject = jsonarray.getJSONObject(i); Log.e("ERROR OBJECT", jsonobject.toString()); } } catch (JSONException e) { e.printStackTrace(); return response; } return "good"; } catch (MalformedURLException e) { e.printStackTrace(); return "fail"; } catch (IOException ee) { ee.printStackTrace(); return "fail"; } }
故障原因
- JSON解析层级完全错误:接口返回的根结构是
JSONObject类型,内容为{"dsdata":{"ttlogin":[{"BundyId":"9090","Name":"IT DEVELOPMENT"}]}},代码直接将整个响应字符串作为JSONArray解析,必然触发类型不匹配异常。实际需要遍历的数组是嵌套在dsdata对象下的ttlogin字段,并非根节点。 - 响应字符集配置错误:请求输出使用
UTF-8编码,读取响应时却硬编码使用iso-8859-1编码,存在返回内容乱码导致解析失败的隐患。浏览器会自动适配响应头的字符集配置,所以不会触发该问题。
修复方案
- 将响应读取的字符集从
iso-8859-1改为UTF-8,和请求编码保持一致。 - 按照接口返回的实际JSON结构逐层解析,不要直接把根节点作为数组处理。
修复后的解析逻辑代码示例:
// 第一步:解析根节点为JSONObject JSONObject rootJson = new JSONObject(response); // 第二步:取出嵌套的dsdata对象 JSONObject dsDataObj = rootJson.getJSONObject("dsdata"); // 第三步:取出ttlogin字段对应的数组,这才是需要遍历的目标数组 JSONArray ttloginArray = dsDataObj.getJSONArray("ttlogin"); for (int i = 0; i < ttloginArray.length(); i++) { JSONObject userObj = ttloginArray.getJSONObject(i); String bundyId = userObj.getString("BundyId"); String name = userObj.getString("Name"); Log.e("LOGIN_INFO", "工号:" + bundyId + ",姓名:" + name); }
内容的提问来源于stack exchange,提问作者Madhab Dhakal
相关产品推荐
相关产品推荐

