1

我尝试将应用程序连接到外部服务,该服务为我提供了一个类似的数组

[{"descr":"my description","id":"123"},...] 

或者在出现错误的情况下

{"error":{"code":123,"message":"my message"}}

有没有办法将其定义为单个类或识别流是哪个对象?


更新 1:我已经通过在循环中运行 100 次并计算平均执行时间来测试多个版本。在所有不同的版本中,我都使用了杰克逊。


这是性能的基线。它不能满足业务需求,因为代码没有区分数组和对象。

fcPhotos = mJsonToObjectMapper.readValue(mFcHttpHelper.doGet(urlString), FcPhotos.class);

照片:平均 100 次处决。持续时间:923ms


使用解析器会使性能降低大约 min。50%

JsonParser jsonParser = mJsonFactory.createJsonParser(mFcHttpHelper.doGet(urlString));

if (jsonParser.nextToken() == JsonToken.START_ARRAY) {
   fcPhotos = mJsonToObjectMapper.readValue(jsonParser, FcPhotos.class);
}

照片:平均 100 次处决。持续时间:1585ms


将 InputStream 转换为 String 并保留 objectMapper.readValue 解决方案会导致:

jsonString = inputStreamToString(urlString);
fcPhotos = mJsonToObjectMapper.readValue(jsonString, FcPhotos.class);

private final String inputStreamToString(final String urlString) throws UnsupportedEncodingException, IOException {
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mFcHttpHelper.doGet(urlString), "UTF8"), 8192);
    StringBuilder stringBuilder = new StringBuilder();
    String line = null;

    while ((line = bufferedReader.readLine()) != null) {
        stringBuilder.append(line + "\n");
    }

    bufferedReader.close();
    return stringBuilder.toString();
}

照片:平均 100 次处决。持续时间:1191ms


更新结束 1


4

1 回答 1

1

一种可能性是使用 JsonParser 查看第一个令牌是什么(JsonToken.START_ARRAY 或 JsonToken.START_OBJECT),然后进行数据绑定。ObjectMapper 可以采用指向第一个事件或尚未移动到第一个事件的 JsonParser。JsonParser/ObjectMapper 的组合在处理根级 JSON 值流时也很好(例如 map/reduce 样式流,或使用 JSON 时的日志条目)。

另一种方法是首先绑定到树模型 (JsonNode; ObjectMapper.readTree()); 查看node是ObjectNode还是ArrayNode,然后使用ObjectMapper.convertValue(rootNode, desiredClass)。这样做的好处是您还可以检查树的属性,以防数组与对象没有区别。

于 2011-02-10T05:38:00.987 回答