JavaRush/Курсы/JSP & Servlets/Добавление body в HttpRequest

Добавление body в HttpRequest

Открыта

3.1 BodyPublishers

Я надеюсь, вы не забыли, что кроме GET-запросов, есть еще PUT и POST-запросы, когда к запросу нужно еще добавить request body, то есть тело запроса.

Для этого у класса HttpRequest есть специальный внутренний класс BodyPublisher. Хотя технически это интерфейс, у которого есть несколько реализаций, о которых мы поговорим ниже

И начнем мы с самой простой – отсутствие тела запроса. Да, бывает и так.

HttpRequest request = HttpRequest.newBuilder()
   .uri(new URI("https://javarush.com"))
   .POST(HttpRequest.BodyPublishers.noBody())
   .build();

Просто и красиво.

3.2 ofString()

Второй самый распространенный вариант – это передать некую строку в качестве request body. Делается это очень просто:

HttpRequest request = HttpRequest.newBuilder()
   .uri(new URI("https://javarush.com"))
   .headers("Content-Type", "text/plain;charset=UTF-8")
   .POST(HttpRequest.BodyPublishers.ofString("Привет"))
   .build();

Кстати, можно задать и кодировку передаваемой строки. Бывает очень полезно, если http-сервер, к которому отправляется запрос, работает не на UTF8.

HttpRequest request = HttpRequest.newBuilder()
   .uri(new URI("https://javarush.com"))
   .POST(HttpRequest.BodyPublishers.ofString("Привет", Charset. US-ASCII)))
   .build();

3.3 ofFile()

Ну и наконец, ты можешь захотеть приложить к POST-запросу файл. Именно таким образом, обычно твои аватарки и заливаются на сервер. Для этого нужно вызвать метод ofFile(), куда передать Path локального файла:

Path avatar = Path.of("c://avatar.jpeg");

HttpRequest request = HttpRequest.newBuilder()
   .uri(new URI("https://javarush.com"))
   .headers("Content-Type", "image/jpeg")
   .POST(HttpRequest.BodyPublishers.ofFile(avatar))
   .build();

3.4 ofByteArray()

Еще один распространенный сценарий – отправить на сервер набор байт. Например, ты сериализовал некий объект в виде набора байт, что-то зашифровал, или просто хочешь переслать некий буфер данных. Для этого понадобится метод .ofByteArray().

В качестве параметра этот метод принимает массив байт. Пример:

byte[] data = "Мое секретное сообщение".getBytes();
byte[] dataEncripted = SuperEncriptor.encript(data);

HttpRequest request = HttpRequest.newBuilder()
   .uri(new URI("https://javarush.com"))
   .headers("Content-Type", "application/octet-stream")
   .POST(HttpRequest.BodyPublishers.ofByteArray(dataEncripted))
   .build();

3.5 ofInputStream()

Наконец последний, но не менее интересный сценарий – это прикрепление InputStream к POST-запросу.

Для этого есть специальная функция – ofInputStream(). И она очень хитрая. Она позволяет организовать пересылку данных из потока в поток, прикрепить к POST-запросу поток данных, который еще даже не открыт

В функцию ofInputStream() нужно передать функцию, которая в качестве результата вернет поток InputStream.

Пример:

byte[] data = "Мое секретное сообщение".getBytes();
//заворачиваем массив байт в поток.
InputStream is = new ByteArrayInputStream(data);

HttpRequest request = HttpRequest.newBuilder()
   .uri(new URI("https://javarush.com"))
   .headers("Content-Type", "application/octet-stream")
   .POST(HttpRequest.BodyPublishers.ofInputStream (() -> is;))
   .build();

Я не стал тут городить огород, но думаю, принцип ты понял. Зачем так сделали? Почти всегда ты можешь воспользоваться методом ofByteArray(). Но если хочешь послать данные асинхронно или нужно реализовать какой-то особо сложный сценарий, то можешь воспользоваться этим методом.

Комментарии (14)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Максим
Уровень 115
10 сентября 2025, 17:41
Не хватает практических задачек
Олег
Уровень 111
Expert
28 июля 2023, 14:57
Могу ошибаться, но компилятор ругается на точку с запятой в этой строчке кода: .POST(HttpRequest.BodyPublishers.ofInputStream (() -> is;))
Anonymous #3268884
Уровень 24
13 августа 2023, 14:21
ага, вот и я думаю, зачем там точка с запятой
Дмитрий
Уровень 108
Expert
15 июня 2023, 08:26
Пункт 3.5, второй абзац, пропущена буква Т Для этого есть специальная функция – ofInputStream(). И она очень хитрая. Она позволяет организовать пересылку данных из потока в поток, прикрепить к POS-запросу поток данных, который еще даже не открыт
jvatechsBackend Developer в Ищу стажировкуExpert
13 июня 2023, 23:58
Хорошо было бы также создать какой-нибудь демо-сервер от Javarush, куда можно было бы отправлять простенькие GET, POST, PUT, DELETE запросы.
Юрий Кохно
Уровень 62
Expert
7 июля 2023, 17:42
Замечательная идея!
jvatechsBackend Developer в Ищу стажировкуExpert
9 июля 2023, 00:07
попробуй следующий фри-сервис: https://jsonplaceholder.typicode.com/ в свое время здорово помог.
Anonymous #3268884
Уровень 24
13 августа 2023, 14:19
супер! А то я, будучи чайником, уже начал обдумывать решение проблемы в чайник-стиле: установить линукс, настроить сервер на своем компе и общаться сам с собой через локалхост
Павел
Уровень 75
Expert
31 мая 2024, 19:00
Работает только с vpn
jvatechsBackend Developer в Ищу стажировкуExpert
13 июня 2023, 23:51
может не:
byte[] dataEncripted = SuperEncriptor.encript(data);
а:
byte[] dataEncrypted = SuperEncryptor.encrypt(data);
и потом, в предыдущей лекции вы предлагаете юзать в основном URI.create вместо new URI дабы избежать выброса исключения, а тут вовсю new URI. Логика?
JavaCoder
Уровень 51
10 января 2023, 09:22
Может не fromFile(), а ofFile() ?
Евгений Frontend Developer
14 октября 2022, 14:00
В п.3.2 можно передать не просто строку, а строку в виде JSON объекта. Как раз такой вариант и применяется на практике.
Сергей Ильин президент
23 января 2023, 11:39
HttpRequest request = HttpRequest.newBuilder() .uri(new URI("https://javarush.com")) .POST(HttpRequest.BodyPublishers.ofString("Привет", Charset. US-ASCII))) .build(); а как получить ответ если пост возвращает строку
jvatechsBackend Developer в Ищу стажировкуExpert
14 июня 2023, 00:02
за ответ видимо отвечает объект HttpResponse, будет что-то типа этого:
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());