Перейти к основному содержимому

Многокомпонентная загрузка с помощью Apache HttpClient

· 4 мин. чтения

1. Обзор

В этом руководстве мы покажем, как выполнить многоэтапную операцию загрузки с помощью HttpClient .

Мы будем использовать http://echo.200please.com в качестве тестового сервера, поскольку он является общедоступным и принимает большинство типов контента.

Если вы хотите копнуть глубже и узнать о других интересных вещах, которые можно делать с помощью HttpClient, — перейдите к основному руководству по HttpClient .

2. Использование метода AddPart

Давайте начнем с рассмотрения объекта MultipartEntityBuilder , чтобы добавить части к объекту Http, который затем будет загружен с помощью операции POST.

Это общий метод добавления частей в HttpEntity , представляющий форму.

Пример 2.1. – Загрузка формы с двумя текстовыми частями и файлом

File file = new File(textFileName);
HttpPost post = new HttpPost("http://echo.200please.com");
FileBody fileBody = new FileBody(file, ContentType.DEFAULT_BINARY);
StringBody stringBody1 = new StringBody("Message 1", ContentType.MULTIPART_FORM_DATA);
StringBody stringBody2 = new StringBody("Message 2", ContentType.MULTIPART_FORM_DATA);
//
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addPart("upfile", fileBody);
builder.addPart("text1", stringBody1);
builder.addPart("text2", stringBody2);
HttpEntity entity = builder.build();
//
post.setEntity(entity);
HttpResponse response = client.execute(post);

Обратите внимание, что мы создаем экземпляр объекта File , также указав значение ContentType , которое будет использоваться сервером.

Также обратите внимание, что метод addPart имеет два аргумента, действующих как пары ключ/значение для формы. Они имеют значение только в том случае, если серверная сторона действительно ожидает и использует имена параметров — в противном случае они просто игнорируются.

3. Использование методов addBinaryBody и addTextBody

Более прямой способ создания составной сущности — использование методов addBinaryBody и AddTextBody . Эти методы работают для загрузки текста, файлов, массивов символов и объектов InputStream . Поясним, как это сделать, на простых примерах.

Пример 3.1. – Загрузка текста и части текстового файла

HttpPost post = new HttpPost("http://echo.200please.com");
File file = new File(textFileName);
String message = "This is a multipart post";
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("upfile", file, ContentType.DEFAULT_BINARY, textFileName);
builder.addTextBody("text", message, ContentType.DEFAULT_BINARY);
//
HttpEntity entity = builder.build();
post.setEntity(entity);
HttpResponse response = client.execute(post);

Обратите внимание, что объекты FileBody и StringBody здесь не нужны.

Также важно, что большинство серверов не проверяют ContentType основного текста, поэтому метод addTextBody может опустить значение ContentType .

API addBinaryBody принимает ContentType , но также возможно создать объект только из двоичного тела и имени параметра формы, содержащего файл. Как указано в предыдущем разделе, некоторые серверы не распознают файл, если значение ContentType не указано.

Далее мы добавим zip-файл в качестве InputStream, а файл изображения будет добавлен как объект File :

Пример 3.2. – Загрузка `` Zip-файла, файла изображения и текстовой части

HttpPost post = new HttpPost("http://echo.200please.com");
InputStream inputStream = new FileInputStream(zipFileName);
File file = new File(imageFileName);
String message = "This is a multipart post";
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody
("upfile", file, ContentType.DEFAULT_BINARY, imageFileName);
builder.addBinaryBody
("upstream", inputStream, ContentType.create("application/zip"), zipFileName);
builder.addTextBody("text", message, ContentType.TEXT_PLAIN);
//
HttpEntity entity = builder.build();
post.setEntity(entity);
HttpResponse response = client.execute(post);

Обратите внимание, что значение ContentType может быть создано «на лету», как в приведенном выше примере для ZIP-файла.

Наконец, не все серверы признают части InputStream . Сервер, который мы создали в первой строке кода, распознает InputStream s.

Давайте теперь посмотрим на другой пример, где addBinaryBody работает напрямую с массивом байтов:

Пример 3.3. – Загрузка массива байтов и текста

HttpPost post = new HttpPost("http://echo.200please.com");
String message = "This is a multipart post";
byte[] bytes = "binary code".getBytes();
//
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("upfile", bytes, ContentType.DEFAULT_BINARY, textFileName);
builder.addTextBody("text", message, ContentType.TEXT_PLAIN);
//
HttpEntity entity = builder.build();
post.setEntity(entity);
HttpResponse response = client.execute(post);

Обратите внимание на ContentType , который теперь определяет двоичные данные.

4. Вывод

В этой статье MultipartEntityBuilder представлен как гибкий объект, который предлагает несколько вариантов API для создания составной формы.

В примерах также показано, как использовать HttpClient для загрузки HttpEntity , аналогичного объекту формы.

Реализацию всех этих примеров и фрагментов кода можно найти в нашем проекте GitHub — это проект на основе Eclipse, поэтому его легко импортировать и запускать как есть.