Java 11 HttpClient multipart/form-data

В этой статье (хотя на статью она не особо тянет, просто заметка, скорее всего) мы научимся отправлять HTTP POST запрос с ContentType: multipart/form-data с помощью встроенного в Java 11 HttpClient.

Тут надо сразу признать, что в самом HttpClient, который вошёл в Java 11, нет особой поддержки multipart/form-data (или я не нашёл?), поэтому большую часть тела запроса приходится формировать вручную.

Для начала нужно понять, что такое multipart/form-data? Этот тип Content-Type используется в первую очередь для отправки файлов на сервер. Тело запроса разделяется на части с помощью последовательности символов-ограничителей (boundary), которые генерируются случайным образом с двумя предваряющими минусами --. Каждая часть содержит один элемент управления формы, который содержит данные файла или другого элемента ввода.

Сама последовательность символов boundary указывается в Content-Type:

Пример запроса multipart/form-data, генерируемого Mozilla Firefox:

А теперь код на Java,который может генерировать аналогичные запросы. Самая сложная часть здесь в ofMultipartData, всё остальное просто обычная инициализация HttpClient:

Странно, что я не смог найти метода, который бы сам делал то, что мы здесь делаем в ofMultipartData. Такого в Java 11 действительно нет, или я что-то пропустил?

В данном примере мы устанавливаем максимальное время ожидания окончания запроса в 10 секунд. По умолчанию эти таймауты устанавливаются в бесконечность. Поэтому важно устанавливать их вручную либо для каждого запроса, либо для всего экземпляра HttpClient.

В учебнике по Java можно найти много другой полезной информации.

Java 11 HttpClient multipart/form-data: 8 комментариев

  1. Федя, привет от Ромы из справочников:)! Спасибо, помогло! Пробовал через спринговый RestTemplate, потом штатным HttpClient’ом без этих ухищрений, потом нагуглил тебя.
    Один вопрос — откуда значение boundary? Просто магическое число (строка)?

    1. Там просто разделитель. Любой набор символов. В данном примере просто захардкожен как магическое число. Но вообще его можно каждый раз просто генерировать заново случайным образом.

  2. Фёдор, добрый день. Не подскажете, чем может быть вызвана ошибка закрытия соединения HttpClient’ом в данном случае?

    upstream prematurely closed connection while reading response header from upstream, client: , server: , request: «POST HTTP/1.1», upstream: «», host: «»

        1. Если честно, я вообще без понятия. Это может быть что угодно. Вплоть до какого-нибудь файрвола.

Добавить комментарий

Ваш адрес email не будет опубликован.