You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中JsonReader解析Neo4j REST API Cypher查询JSON结果报错排查

嘿,这个问题我遇到过类似的情况,咱们一步步来解决它!

首先得明确Neo4j REST API返回的JSON结构——根节点是一个对象,不是数组也不是字符串,里面包含columns(一维数组)和data(二维数组)两个字段。你之前的错误就是没按这个结构来解析,直接去读字符串或者错误地开启数组解析,才会抛出Expected a string but was BEGIN_ARRAY异常。

下面给你两种可行的解析方案,都基于你用的Google Simple JSON库:

方案一:用JsonReader流式解析(适合大体积JSON)

这种方式逐字符读取,内存占用低,适合返回数据量较大的场景,关键是要严格匹配JSON的层级结构:

// 先获取HTTP响应的实体
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();

// 创建JsonReader并开始解析根对象
JsonReader reader = new JsonReader(new InputStreamReader(entity.getContent()));
reader.beginObject(); // 根是对象,必须先调用这个

while (reader.hasNext()) {
    String fieldName = reader.nextName();
    switch (fieldName) {
        case "columns":
            // 处理columns一维数组
            reader.beginArray();
            while (reader.hasNext()) {
                String column = reader.nextString();
                // 这里可以把列名存入集合,比如List<String> columnsList.add(column);
            }
            reader.endArray();
            break;
        case "data":
            // 处理data二维数组(每个元素又是一个数组)
            reader.beginArray();
            while (reader.hasNext()) {
                reader.beginArray(); // 开启每一行的数组
                while (reader.hasNext()) {
                    String value = reader.nextString();
                    // 处理单个数据值,比如"1607174"
                }
                reader.endArray(); // 结束当前行的数组
            }
            reader.endArray();
            break;
        default:
            reader.skipValue(); // 跳过其他未知字段,避免解析出错
            break;
    }
}

reader.endObject(); // 结束根对象解析
reader.close();

方案二:用JSONObject一次性解析(更直观)

如果返回的JSON数据量不大,直接把响应转成字符串后用JSONObject解析会更简单,不容易出错:

// 把HTTP响应实体转成字符串
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
String jsonStr = EntityUtils.toString(entity);

// 解析成JSONObject
JSONObject rootObj = new JSONObject(jsonStr);

// 获取columns数组
JSONArray columnsArr = rootObj.getJSONArray("columns");
for (int i = 0; i < columnsArr.length(); i++) {
    String columnName = columnsArr.getString(i);
    // 处理列名
}

// 获取data二维数组
JSONArray dataArr = rootObj.getJSONArray("data");
for (int i = 0; i < dataArr.length(); i++) {
    JSONArray rowArr = dataArr.getJSONArray(i);
    for (int j = 0; j < rowArr.length(); j++) {
        String dataValue = rowArr.getString(j);
        // 处理每个数据值,比如你的"1607174"
    }
}

关键注意点

  1. 必须先解析根对象:Neo4j返回的是{...},所以第一步要调用beginObject()(流式解析)或者直接用JSONObject包裹(一次性解析),不能直接去读字符串或开启数组。
  2. 层级要对应:每个beginArray()必须有对应的endArray(),每个beginObject()必须有对应的endObject(),否则会抛出解析异常。
  3. 跳过未知字段:如果API返回了额外字段,一定要用skipValue()跳过,避免解析中断。

内容的提问来源于stack exchange,提问作者Thomas Morgan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:42:48