Android RecyclerView中解析非标准JSON对象流的问题咨询
问题解决方案
报错根因
你当前遇到的org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject报错和JSON拼接格式无关,是网络请求代码逻辑错误导致的:
- 你直接使用
urlConnection.getErrorStream()读取返回内容,该流仅在接口返回4xx/5xx错误状态码时才有值,你实际拿到的是错误页面的HTML内容,开头为<!DOCTYPE,自然无法转换为JSONObject。 - 正常请求成功的返回内容需要从
urlConnection.getInputStream()读取,需要先判断请求状态码再选择对应流。
拼接JSONObject的解析方案
多个直接拼接的JSONObject不需要强制要求后端修改为标准JSON格式,完全可以自行拆分解析,有两种常用实现方案:
方案1:大括号匹配拆分(兼容性最好)
通过统计大括号层数拆分单个完整JSON对象,不受JSON内部转义字符影响:
List<JSONObject> objectList = new ArrayList<>(); int bracketCount = 0; StringBuilder currentJson = new StringBuilder(); for (char c : s.toCharArray()) { if (c == '{') bracketCount++; if (bracketCount > 0) currentJson.append(c); if (c == '}') { bracketCount--; if (bracketCount == 0) { // 已拿到完整的单个JSON对象 objectList.add(new JSONObject(currentJson.toString())); currentJson.setLength(0); // 清空缓存准备解析下一个 } } }
拿到objectList后遍历每个对象执行你原有解析逻辑,将字段存入对应列表即可喂给RecyclerView Adapter。
方案2:转换为标准JSON数组(代码最简)
对返回字符串做简单格式化,直接转为JSONArray解析,注意要过滤掉末尾不完整的半截JSON:
s = s.trim(); // 过滤示例末尾不完整的单独{ if (s.endsWith("{")) { s = s.substring(0, s.length() - 1); } // 替换拼接符、首尾加数组括号,转为标准JSON数组格式 String arrayFormatStr = "[" + s.replace("}{", "},{") + "]"; JSONArray jsonArray = new JSONArray(arrayFormatStr); // 遍历数组解析所有字段 for (int i = 0; i < jsonArray.length(); i++) { JSONObject obj = jsonArray.getJSONObject(i); // 原有解析逻辑 JSONObject toNameObject = obj.getJSONObject("to"); toNameList.add(toNameObject.getString("name")); JSONObject fromNameObject = obj.getJSONObject("from"); fromNameList.add(fromNameObject.getString("name")); timeStampList.add(obj.getString("timestamp")); }
原有请求代码修复点
修改网络请求部分的流读取逻辑:
int statusCode = urlConnection.getResponseCode(); InputStream in; // 根据状态码选择正确的读取流 if (statusCode >= 200 && statusCode < 300) { in = urlConnection.getInputStream(); } else { in = urlConnection.getErrorStream(); } InputStreamReader isw = new InputStreamReader(in); // 后续流读取逻辑不变
补充说明:AsyncTask已在Android 11及以上版本废弃,长期迭代建议替换为OkHttp、Retrofit等成熟网络请求框架。
内容的提问来源于stack exchange,提问作者beastlyCoder
相关产品推荐
相关产品推荐

