Статья

Загрузка файлов в Java с использованием Apache HttpClient

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

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

Давайте начнем с рассмотрения класса MultipartEntityBuilder для добавления данных в Http-объект, который затем будет загружен с помощью POST-операции.
Это универсальный метод для добавления данных в HttpEntity, представляющий форму.
File file = new File(textFileName);
HttpPost post = new HttpPost("http://test.com");
FileBody fileBody = new FileBody(file, ContentType.DEFAULT_BINARY);
StringBody stringBody1 = new StringBody("Сообщение 1", ContentType.MULTIPART_FORM_DATA);
StringBody stringBody2 = new StringBody("Сообщение 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 имеет два аргумента, действующих как пары ключ/значение для формы. Они актуальны только в том случае, когда серверная сторона действительно ожидает и использует имена параметров – в противном случае они просто игнорируются.

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

Другой способ создать multipart сущность – использовать методы addBinaryBody и addTextBody. Эти методы нужны для загрузки текста, файлов, массивов символов и объектов InputStream. Давайте проиллюстрируем это на простых примерах.
HttpPost post = new HttpPost("http://test.com");
File file = new File(textFileName);
String message = "Это составной post-запрос";
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("upload_file", 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.

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

Теперь мы добавим zip-файл в качестве InputStream, в то время как файл изображения будет добавлен в качестве объекта File:
HttpPost post = new HttpPost("http://test.com");
InputStream inputStream = new FileInputStream(zipFileName);
File file = new File(imageFileName);
String message = "Это составной post-запрос";
MultipartEntityBuilder builder = MultipartEntityBuilder.create();         
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody
  ("up_file", file, ContentType.DEFAULT_BINARY, imageFileName);
builder.addBinaryBody
  ("up_stream", 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-файла.

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

Давайте теперь посмотрим на другой пример, где addBinaryBody работает непосредственно с массивом байтов:
HttpPost post = new HttpPost("http://test.com");
String message = "Это составной post-запрос";
byte[] bytes = "binary code".getBytes(); 

MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("up_file", 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, который теперь задает двоичные данные.

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

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