Как я могу сделать запрос 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 для многостраничных/формальных данных?
Предпосылки: Я хочу использовать Удаленный API Zoho Writer.
Ответы
Ответ 1
Мы используем HttpClient 4.x для создания многостраничного сообщения.
ОБНОВЛЕНИЕ: с 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();
Ниже приведен оригинальный фрагмент кода с устаревшим API HttpClient 4.0:
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 в 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
Если размер JAR имеет значение (например, в случае апплета), можно также напрямую использовать httpmime с java.net.HttpURLConnection вместо 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
код:
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();
...
Зависимость в pom.xml:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.2.4</version>
</dependency>
Ответ 4
Используйте этот код для загрузки изображений или любых других файлов на сервер с помощью сообщения в multipart.
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
public class SimplePostRequestTest {
public static void main(String[] args) throws UnsupportedEncodingException, IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://192.168.0.102/uploadtest/upload_photo");
try {
FileBody bin = new FileBody(new File("/home/ubuntu/cd.png"));
StringBody id = new StringBody("3");
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("upload_image", bin);
reqEntity.addPart("id", id);
reqEntity.addPart("image_title", new StringBody("CoolPic"));
httppost.setEntity(reqEntity);
System.out.println("Requesting : " + httppost.getRequestLine());
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httppost, responseHandler);
System.out.println("responseBody : " + responseBody);
} catch (ClientProtocolException e) {
} finally {
httpclient.getConnectionManager().shutdown();
}
}
}
для загрузки требуется файлы ниже.
Библиотеки
httpclient-4.1.2.jar,
httpcore-4.1.2.jar,
httpmime-4.1.2.jar,
httpclient-cache-4.1.2.jar,
commons-codec.jar
и
commons-logging-1.1.1.jar
, чтобы быть в пути к классам.
Ответ 5
Вы также можете использовать REST Assured, который основывается на HTTP-клиенте. Это очень просто:
given().multiPart(new File("/somedir/file.bin")).when().post("/fileUpload");
Ответ 6
httpcomponents-client-4.0.1
работал у меня. Однако мне пришлось добавить внешний баннер apache-mime4j-0.6.jar
(org.apache.james.mime4j), иначе
reqEntity.addPart("bin", bin);
не будет компилироваться. Теперь он работает как шарм.
Ответ 7
Я нашел этот образец в руководстве Apache Quickstart. Это для версии 4.5:
/**
* Example how to use multipart/form encoded POST request.
*/
public class ClientMultipartFormPost {
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.out.println("File path not given");
System.exit(1);
}
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpPost httppost = new HttpPost("http://localhost:8080" +
"/servlets-examples/servlet/RequestInfoExample");
FileBody bin = new FileBody(new File(args[0]));
StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("bin", bin)
.addPart("comment", comment)
.build();
httppost.setEntity(reqEntity);
System.out.println("executing request " + httppost.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httppost);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
System.out.println("Response content length: " + resEntity.getContentLength());
}
EntityUtils.consume(resEntity);
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
}
Ответ 8
У нас есть чистая реализация Java-представлений с множественной формой без каких-либо внешних зависимостей или библиотек вне jdk. См. Https://github.com/atulsm/https-multipart-purejava/blob/master/src/main/java/com/atul/MultipartPure.java
private static String body = "{\"key1\":\"val1\", \"key2\":\"val2\"}";
private static String subdata1 = "@@ -2,3 +2,4 @@\r\n";
private static String subdata2 = "<data>subdata2</data>";
public static void main(String[] args) throws Exception{
String url = "https://" + ip + ":" + port + "/dataupload";
String token = "Basic "+ Base64.getEncoder().encodeToString((userName+":"+password).getBytes());
MultipartBuilder multipart = new MultipartBuilder(url,token);
multipart.addFormField("entity", "main", "application/json",body);
multipart.addFormField("attachment", "subdata1", "application/octet-stream",subdata1);
multipart.addFormField("attachment", "subdata2", "application/octet-stream",subdata2);
List<String> response = multipart.finish();
for (String line : response) {
System.out.println(line);
}
}