我怎样才能使用Java做一个多部分/表单数据POST请求?

在Apache Commons HttpClient 3.x版本的日子里,可以做一个多部分/表单数据POST请求( 从2004年开始的一个例子 )。 不幸的是,在HttpClient 4.0版本中这是不可能的 。

对于我们的核心活动“HTTP”,multipart有点超出范围。 我们希望使用由其他项目维护的多部分代码,但是我不知道。 几年前,我们试图将多部分代码转换为共享编解码器,但是我并没有在那里起飞。 Oleg最近提到了另一个具有多部分解析代码的项目,可能对我们的多部分格式代码感兴趣。 我不知道目前的状况。 ( http://www.nabble.com/multipart-form-data-in-4.0-td14224819.html )

有没有人知道任何Java库,允许我写一个HTTP客户端,可以做一个多部分/表单数据POST请求?

背景:我想使用Zoho Writer的Remote API 。

我们使用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(); 

以下是不赞成使用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(); 

这些是我拥有的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> 

如果JAR的大小很重要(例如applet),也可以直接使用java.net.HttpURLConnection而不是HttpClient来使用httpmime。

 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> 

使用此代码将图像或任何其他文件上传到服务器使用邮政多部分。

 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.jarcommons-logging-1.1.1.jar在类路径中。

您也可以使用基于HTTP客户端的REST Assured 。 这很简单:

 given().multiPart(new File("/somedir/file.bin")).when().post("/fileUpload"); 

httpcomponents-client-4.0.1为我工作。 但是,我不得不添加外部jar apache-mime4j-0.6.jarorg.apache.james.mime4j )否则reqEntity.addPart("bin", bin); 不会编译。 现在它像魅力一样工作。