Вопрос-ответ

How can I make a multipart/form-data POST request using Java?

Как я могу сделать POST-запрос multipart / form-data с использованием Java?

Во времена версии 3.x Apache Commons HttpClient выполнение POST-запроса, состоящего из нескольких частей / данных формы, было возможно (пример 2004 г.). К сожалению, это больше невозможно в версии 4.0 HttpClient.


Для нашего основного действия "HTTP" multipart несколько выходит за рамки. Мы хотели бы использовать составной код, поддерживаемый каким-либо другим проектом, для которого он входит в область действия, но я не знаю ни одного. Несколько лет назад мы пытались перенести составной код в commons-codec, но у меня ничего не вышло. Олег недавно упомянул другой проект с составным кодом синтаксического анализа, и его может заинтересовать наш составной код форматирования. Я не знаю текущего состояния этого. (http://www.nabble.com/multipart-form-data-in-4.0-td14224819.html)


Кто-нибудь знает о какой-либо библиотеке Java, которая позволяет мне написать HTTP-клиент, который может выполнять POST-запрос multipart / form-data?

Справочная информация: я хочу использовать удаленный API Zoho Writer.

Переведено автоматически
Ответ 1

Мы используем HttpClient 4.x для создания post из нескольких частей файла.

ОБНОВЛЕНИЕ: начиная с HttpClient 4.3, некоторые классы устарели. Вот код с новым API.:

CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost uploadFile = new HttpPost("...");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("field1", "yes", ContentType.TEXT_PLAIN);

// This attaches the file to the POST:
File f = new File("[/path/to/upload]");
builder.addBinaryBody(
"file",
new FileInputStream(f),
ContentType.APPLICATION_OCTET_STREAM,
f.getName()
);

HttpEntity multipart = builder.build();
uploadFile.setEntity(multipart);
CloseableHttpResponse response = httpClient.execute(uploadFile);
HttpEntity responseEntity = response.getEntity();

Ниже приведен исходный фрагмент кода с устаревшим HttpClient 4.0 API:

HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);

FileBody bin = new FileBody(new File(fileName));
StringBody comment = new StringBody("Filename: " + fileName);

MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("bin", bin);
reqEntity.addPart("comment", comment);
httppost.setEntity(reqEntity);

HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
Ответ 2

Это зависимости Maven, которые у меня есть.

Код Java:

HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);

FileBody uploadFilePart = new FileBody(uploadFile);
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("upload-file", uploadFilePart);
httpPost.setEntity(reqEntity);

HttpResponse response = httpclient.execute(httpPost);

Maven Dependencies in pom.xml:

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.0.1</version>
<scope>compile</scope>
</dependency>
Ответ 3

If size of the JARs matters (e.g. in case of applet), one can also directly use httpmime with java.net.HttpURLConnection instead of HttpClient.

httpclient-4.2.4:      423KB
httpmime-4.2.4: 26KB
httpcore-4.2.4: 222KB
commons-codec-1.6: 228KB
commons-logging-1.1.1: 60KB
Sum: 959KB

httpmime-4.2.4: 26KB
httpcore-4.2.4: 222KB
Sum: 248KB

Code:

HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");

FileBody fileBody = new FileBody(new File(fileName));
MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.STRICT);
multipartEntity.addPart("file", fileBody);

connection.setRequestProperty("Content-Type", multipartEntity.getContentType().getValue());
OutputStream out = connection.getOutputStream();
try {
multipartEntity.writeTo(out);
} finally {
out.close();
}
int status = connection.getResponseCode();
...

Dependency in pom.xml:

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.2.4</version>
</dependency>
Ответ 4

Here's a solution that does not require any libraries.

This routine transmits every file in the directory d:/data/mpf10 to urlToConnect


String boundary = Long.toHexString(System.currentTimeMillis());
URLConnection connection = new URL(urlToConnect).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
writer = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
File dir = new File("d:/data/mpf10");
for (File file : dir.listFiles()) {
if (file.isDirectory()) {
continue;
}
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\"" + file.getName() + "\"; filename=\"" + file.getName() + "\"");
writer.println("Content-Type: text/plain; charset=UTF-8");
writer.println();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
for (String line; (line = reader.readLine()) != null;) {
writer.println(line);
}
} finally {
if (reader != null) {
reader.close();
}
}
}
writer.println("--" + boundary + "--");
} finally {
if (writer != null) writer.close();
}
// Connection is lazily executed whenever you request any status.
int responseCode = ((HttpURLConnection) connection).getResponseCode();
// Handle response
java