如何以块的形式获取JSON数据以报告进度?

时间:2011-07-14 23:25:00

标签: java json httpclient inputstream

我需要通过REST API下载联系人数据,我以JSON格式获取。问题是,它可能是很多联系人,所以我想观察进度(已经下载了多少联系人)并向用户报告(带有进度条,下面的代码在一个帖子中运行)。

然而,似乎行client.execute(getRequest);建立连接并一次性下载整个内容,即我的InputStream阅读器(以块为单位获取内容)似乎没用。现在我想知道如何让它以块的形式工作,所以我可以报告进展情况吗?

/** prepare HTML get request */
HttpGet getRequest = new HttpGet(url[0]);
getRequest.addHeader("Authorization", "OAuth " + myTokens.get_access_token());

/** execute HTML request */
DefaultHttpClient client = new DefaultHttpClient();
JSONArray records = null;
HttpResponse response = client.execute(getRequest);

/** init response handlers for input stream */
InputStream input = new BufferedInputStream(response.getEntity().getContent());

byte data[] = new byte[MAX_BUFFER_SIZE];

long totalContactsCount = -1;
int readContactsCount = 0;
int currentByteReadCount = 0;

/** read response from inpus stream */
while ((currentByteReadCount = input.read(data)) != -1) {
    String readData = new String(data, 0, currentByteReadCount);
    dataString.append(readData);

    // then +1 progress on every ...},{... (JSON object separator)
    if (readData.indexOf("},{") >= 0) {
        readContactsCount++;
    }

    // publishing the progress....
    if (totalContactsCount > 0) {
        publishProgress((int)(readContactsCount * 100 / totalContactsCount));
    }
}
input.close();

/** transform response into JSONArray */
String result = dataString.toString();

//... convert into JSONArray

3 个答案:

答案 0 :(得分:2)

不幸的是,正如DefaultHttpClient上的文档所示,execute方法返回已经解析的HTTP响应,因此已经从网络中读取,因此您无法插入输入流。该流已准备好供您阅读,但一旦它被检索,就像您已经注意到的那样。你必须使用另一种策略。例如,使用套接字API尝试连接。

答案 1 :(得分:1)

您可以先向网络服务询问其拥有的联系人总数(比如100,000),然后向其询问联系人的个人“页面”(例如100个联系人/页)。每个页面到达时,您都会更新进度条。如果页面请求失败,只需重试该请求并继续处理。与尝试在一个大规模请求中获取所有100k联系人相比,这应该是一种更加可靠和有效的方法。

答案 2 :(得分:1)

您可能需要查看this stackoverflow thread,其中提出了类似的问题。从那里看来this website可能是相关的。