Как использовать потоковый HTTP-ответ в Java? - PullRequest
0 голосов
/ 17 апреля 2020

У меня проблемы с попыткой использовать отклик конечной точки HTTP, которая непрерывно передает события в реальном времени. На самом деле это одна из конечных точек Docker: https://docs.docker.com/engine/api/v1.40/#operation / SystemEvents

Я использую Apache HTTP Client 4.5.5, и он просто останавливается на неопределенный срок, когда я пытаюсь использовать content InputStream:

HttpEntity entity = resp.getEntity();
EntityUtils.consume(entity);//it just hangs here.
//Even if I don't call this method, Apache calls it automatically
//after running all my ResponseHandlers

По-видимому, это можно сделать с помощью необработанного JDK URL: Передать HTTP-ответ в Java

Но я не могу сделать что локальный Docker связывается через сокет Unix, который мне удалось настроить только в HTTP-клиенте Apache с сторонней библиотекой для Unix сокетов в Java.

Если есть это умная клиентская библиотека HTTP, на которую я мог бы переключиться, это также было бы вариантом.

Любые идеи будут с благодарностью. Спасибо!

1 Ответ

0 голосов
/ 21 апреля 2020

Мне удалось решить эту проблему, сгенерировав бесконечный java.util.stream.Stream из JsonObject из ответа InputStream (я знаю, что чтение части json не самое элегантное решение, но лучшего способа с этим API, а также , Docker не отправляет разделитель между jsons).

final InputStream content = response.getEntity().getContent();
final Stream<JsonObject> stream = Stream.generate(
    () -> {
        JsonObject read = null;
        try {
            final byte[] tmp = new byte[4096];
            while (content.read(tmp) != -1) {
                try {
                    final JsonReader reader = Json.createReader(
                        new ByteArrayInputStream(tmp)
                    );
                    read = reader.readObject();
                    break;
                } catch (final Exception exception) {
                    //Couldn't parse byte[] to Json,
                    //try to read more bytes.
                }
            }
        } catch (final IOException ex) {
            throw new IllegalStateException(
                "IOException when reading streamed JsonObjects!"
            );
        }
        return read;
    }
).onClose(
    () -> {
        try {
             ((CloseableHttpResponse) response).close();
        } catch (final IOException ex) {
            //There is a bug in Apache HTTPClient, when closing
            //an infinite InputStream: IOException is thrown
            //because the client still tries to read the remainder
            // of the closed Stream. We should ignore this case.
        }
    }
);
return stream;
...