使用 AsyncHttpClient 接收部分响应正文

Receiving Partial Response Body Using AsyncHttpClient

我正在使用 AsyncHttpClient 编写 REST 服务使用者 class。服务 returns 一个 JSON 响应字符串,其中包含很多我不需要的额外数据。我只对收到的回复的特定部分感兴趣。

例如,考虑以下 JSON Response

{
    "decisions": {
        "foo": "foo",
        "bar": "bar"
    }
    "internals": {
        "foobar": "foobar"
    }
}

现在,我只对 decisions 对象感兴趣,不想浪费时间和内存来获取 internals,因为这在实际响应中很大,我不需要它。

是否可以使用AsyncHttpClient?我该如何实现?

这是我的 class 的代码片段:

AsyncHttpClient c = new AsyncHttpClient();
Future<String> f = c.prepareGet("http://www.foo.org/ba").execute(new AsyncHandler<String>() {
    private ByteArrayOutputStream bytes = new ByteArrayOutputStream();

    @Override
    public STATE onStatusReceived(HttpResponseStatus status) throws Exception {
        return STATE.CONTINUE;
    }

    @Override
    public STATE onHeadersReceived(HttpResponseHeaders h) throws Exception {
         return STATE.CONTINUE;
    }

    @Override
    public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
         /* What shall I write here? */
         return STATE.CONTINUE;
    }

    @Override
    public String onCompleted() throws Exception {
         return bytes.toString("UTF-8");
    }

    @Override
    public void onThrowable(Throwable t) {
        /* TODO : Throw Exception */
    }
});

String bodyResponse = f.get();

HTTP 建立在 TCP 之上,因此它本质上是分块的。您会收到 onBodyPartReceived 字节 的那些块的通知。这些块的长度通常是一个 MTU.

您要实现的目标需要:

  • 您确定您要查找的内容在第一个块中
  • 您肯定知道您不会得到未映射到您的字符编码的空闲字节(单个字符编码为 2 个或更多字节,并跨越 2 个连续的块)。你只能确定你的编码是 US-ASCII,而不是 UTF-8。
  • 您可以使用 JSON 解析器(可能是正则表达式)以外的其他东西来解析您的部分响应正文,因为您不会获得有效的 JSON 有效负载。

如果您可以确保所有这些假设都有效,则可以在 onBodyPartReceived 和 return STATE.ABORT.

中进行提取