Эта статья представляет собой сверхзвуковое руководство по работе с типами тел запросов и ответов в API-интерфейсе HTTP-клиента. Давайте начнем с типов тела запроса.
Типы тел запроса на обработку
Задание тела запроса может быть выполнено с помощью HttpRequest.Builder.POST()
и PUT()
или с помощью method()
(например, method("PATCH", HttpRequest.BodyPublisher)
). POST()
И PUT()
принять аргумент HttpRequest.BodyPublisher
типа.
API поставляется с несколькими реализациями этого интерфейса ( BodyPublisher
) в HttpRequest.BodyPublishers
классе:
-
BodyPublishers.ofString()
-
BodyPublishers.ofFile()
-
BodyPublishers.ofByteArray()
-
BodyPublishers.ofInputStream()
Мы рассмотрим эти реализации в следующих разделах.
Создание тела из строки
Создание тела из строки может быть выполнено с использованием BodyPublishers.ofString()
, как показано в следующем фрагменте кода:
Джава
1
HttpRequest requestBody = HttpRequest.newBuilder()
2
.header("Content-Type", "application/json")
3
.POST(HttpRequest.BodyPublishers.ofString(
4
"{\"name\": \"morpheus\",\"job\": \"leader\"}"))
5
.uri(URI.create("https://reqres.in/api/users"))
6
.build();
Для указания вызова по кодировке используйте ofString(String s, Charset charset)
.
Создание тела из InputStream
Создание тела из InputStream
может быть выполнено с использованием BodyPublishers.ofInputStream()
, как показано в следующем фрагменте кода. (Здесь мы рассчитываем ByteArrayInputStream
, но, конечно, InputStream
подойдет любой другой ):
Джава
xxxxxxxxxx
1
HttpRequest requestBodyOfInputStream = HttpRequest.newBuilder()
2
.header("Content-Type", "application/json")
3
.POST(HttpRequest.BodyPublishers.ofInputStream(()
4
-> inputStream("user.json")))
5
.uri(URI.create("https://reqres.in/api/users"))
6
.build();
7
8
private static ByteArrayInputStream inputStream(String fileName) {
9
10
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(
11
Files.readAllBytes(Path.of(fileName)))) {
12
return inputStream;
13
} catch (IOException ex) {
14
throw new RuntimeException("File could not be read", ex);
15
}
16
}
Чтобы воспользоваться ленивым творением, InputStream
нужно пройти как Supplier
.
Создание тела из байтового массива
Создание тела из байтового массива может быть выполнено с использованием BodyPublishers.ofByteArray()
, как показано в следующем фрагменте кода:
Джава
1
HttpRequest requestBodyOfByteArray = HttpRequest.newBuilder()
2
.header("Content-Type", "application/json")
3
.POST(HttpRequest.BodyPublishers.ofByteArray(
4
Files.readAllBytes(Path.of("user.json"))))
5
.uri(URI.create("https://reqres.in/api/users"))
6
.build();
Мы также можем отправить только часть байтового массива, используя ofByteArray(byte[] buf, int offset, int length)
. Кроме того, мы можем предоставить данные из Iterable
байтовых массивов, используя ofByteArrays(Iterable<byte[]> iter)
.
Создание тела из файла
Создание тела из файла может быть выполнено с использованием BodyPublishers.ofFile()
, как показано в следующем фрагменте кода:
Джава
xxxxxxxxxx
1
HttpRequest requestBodyOfFile = HttpRequest.newBuilder()
2
.header("Content-Type", "application/json")
3
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("user.json")))
4
.uri(URI.create("https://reqres.in/api/users"))
5
.build();
Все приведенные выше примеры можно найти на GitHub . Далее давайте разберемся с типами тела ответа.
Обработка типов тела ответа
Обработка ответных типов телосложения может быть выполнена с помощью HttpResponse.BodyHandler
.
API поставляется с несколькими реализациями этого интерфейса ( BodyHandler
) в HttpResponse.BodyHandlers
классе:
-
BodyHandlers.ofByteArray()
-
BodyHandlers.ofFile()
-
BodyHandlers.ofString()
-
BodyHandlers.ofInputStream()
-
BodyHandlers.ofLines()
Рассматривая следующий запрос, давайте рассмотрим несколько решений для обработки тела ответа:
Джава
xxxxxxxxxx
1
HttpClient client = HttpClient.newHttpClient();
2
3
HttpRequest request = HttpRequest.newBuilder()
4
.uri(URI.create("https://reqres.in/api/users/2"))
5
.build();
Мы рассмотрим, как обрабатывать различные типы тел ответов в следующих разделах.
Обработка тела ответа как строки
Обработка ответа тела в виде строки может быть выполнена с использованием BodyHandlers.ofString()
, как показано в следующем фрагменте кода:
Джава
xxxxxxxxxx
1
HttpResponse<String> responseOfString
2
= client.send(request, HttpResponse.BodyHandlers.ofString());
3
4
System.out.println("Status code: " + responseOfString.statusCode());
5
System.out.println("Body: " + responseOfString.body());
Для указания кодировки звоните ofString(String s, Charset charset)
.
Обработка тела ответа в виде файла
Обработка ответа тела в виде файла может быть выполнена с использованием BodyHandlers.ofFile()
, как показано в следующем фрагменте кода:
Джава
xxxxxxxxxx
1
HttpResponse<Path> responseOfFile = client.send(
2
request, HttpResponse.BodyHandlers.ofFile(
3
Path.of("response.json")));
4
5
System.out.println("Status code: " + responseOfFile.statusCode());
6
System.out.println("Body: " + responseOfFile.body());
Для уточнения открытых опций звоните ofFile(Path file, OpenOption... openOptions)
.
Обработка тела ответа как байтового массива
Обработка ответа тела в виде байтового массива может быть выполнена с использованием BodyHandlers.ofByteArray()
, как показано в следующем фрагменте кода:
Джава
xxxxxxxxxx
1
HttpResponse<byte[]> responseOfByteArray = client.send(
2
request, HttpResponse.BodyHandlers.ofByteArray());
3
4
System.out.println("Status code: "
5
+ responseOfByteArray.statusCode());
6
System.out.println("Body: "
7
+ new String(responseOfByteArray.body()));
Для использования байтового массива вызовите ofByteArrayConsumer(Consumer<Optional<byte[]>> consumer)
.
Обработка тела ответа как входного потока
Обработка ответа тела как InputStream может быть выполнена с использованием BodyHandlers.ofInputStream()
, как показано в следующем фрагменте кода:
Джава
xxxxxxxxxx
1
HttpResponse<InputStream> responseOfInputStream = client.send(
2
request, HttpResponse.BodyHandlers.ofInputStream());
3
4
System.out.println("\nHttpResponse.BodyHandlers.ofInputStream():");
5
System.out.println("Status code: "
6
+ responseOfInputStream.statusCode());
7
8
byte[] allBytes;
9
try (InputStream fromIs = responseOfInputStream.body()) {
10
allBytes = fromIs.readAllBytes();
11
}
12
13
System.out.println("Body: "
14
+ new String(allBytes, StandardCharsets.UTF_8));
Обработка тела ответа как потока строк
Обработка ответа тела в виде потока строк может быть выполнена с использованием BodyHandlers.ofLines()
, как показано в следующем фрагменте кода:
Джава
xxxxxxxxxx
1
HttpResponse<Stream<String>> responseOfLines = client.send(
2
request, HttpResponse.BodyHandlers.ofLines());
3
4
System.out.println("Status code: " + responseOfLines.statusCode());
5
System.out.println("Body: " + responseOfLines.body().collect(toList()));
Все приведенные выше примеры можно найти на GitHub .
Если вам понравилась эта статья, то я уверен, что вам понравится моя книга « Проблемы кодирования Java» , в которой есть целая глава, посвященная HTTP Client API. Проверьте это!