Как передать тело HTTP-запроса с помощью Java

У меня есть InputStream и размер данных, которые будут выведены (ответ на HTTP-запрос). По причинам сложности места я не могу прочитать все это. Я хочу отправить данные непосредственно в новое тело запроса. Я пытался сделать это с OkHttp, но не могу заставить его работать. Я не знаю других HTTP-клиентов, которые могут это делать.

Если это вообще возможно, я бы хотел не возиться с Socket. Любой совет?

Обновлено: добавлено ограничение: решение должно работать с Java 8.

stackoverflow.com/q/27371201/461499 ?
Rob Audenaerde 06.02.2019 13:11

@RobAu нет, этот вопрос касается потоковой передачи ответа. Я хочу передать запрос

Jurgen Voorneveld 06.02.2019 13:49
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
2
3 038
2

Ответы 2

Я считаю, что новый HttpClient, стандартизированный в Java 11, должен позволить вам это сделать. Он использует API Flow (реактивные потоки), и вы можете предоставить BodyHandler/BodySubscriber, который будет запрашивать/получать байты по мере их поступления. HttpClient также позволяет указать BodyPublisher при отправке запроса. Таким образом, это должно быть только вопросом привязки подписки, пересылаемой издателем запроса своим подписчикам, к подписке, переданной BodySubscriber стеком Http, а затем BodySubscriberonNext (и т. д.) вызывает соответствующие методы подписчика Publisher. Обратите внимание, что это академическое описание: на самом деле я не пытался его реализовать. Для настройки ссылки на подписку может потребоваться некоторое размышление и некоторые хитрости, но я считаю, что это должно сработать.

Однако убедитесь, что ваша реализация BodySubscriber/BodyPublisher придерживается семантики реактивных потоков и что они не блокируются в обратных вызовах.

https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.htmlhttps://openjdk.java.net/groups/net/httpclient/intro.html

Если подумать, возможно, это не то, о чем вы просите: если у вас уже есть InputStream, все еще проще: просто используйте BodyPublishers.ofInputStream при отправке запроса.

https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpRequest.BodyPublishers.html#ofInputStream(java.util.function.Supplier)

Это действительно круто. Увы, корпоративная среда, в которой я работаю, застряла на Java 8, и мне не разрешено обновляться.

Jurgen Voorneveld 06.02.2019 15:18

О - очень плохо. можно ли использовать экзекьютор для прокачки InputStream и передачи его в запрос? Старый устаревший стек http (HttpURLConnection) предоставляет тело запроса как OutputStream, поэтому, если вы можете использовать поток исполнителя для передачи...

daniel 06.02.2019 15:34

Я думал об этом, но классы HttpURLConnection настолько сломаны, что, вероятно, проще просто использовать обычный сокет и написать запрос вручную.

Jurgen Voorneveld 06.02.2019 15:46

Ну, есть причина иметь новый API в 11... Что касается непосредственного использования простого сокета, вы можете быть удивлены всеми маленькими темными углами, которые скрываются в любой реализации HTTP.

daniel 06.02.2019 16:03

Я бы добавил, что если размер запроса достаточен для реализации его потоковой передачи, вполне вероятно, что служба-получатель также захочет реализовать потоковую передачу.

Также верно, что, хотя старый существующий класс HttpUrlConnection или что-либо, что обеспечивает доступ к потокам ввода и вывода, связанным с данным соединением URL, может поддерживать потоковую передачу, также вероятно, что вам придется кодировать чрезмерное количество поддержки для более новой безопасности. проблемы, такие как ОПЦИИ.

Другие вопросы по теме