2009-09-04 46 views
78

Trong những ngày của phiên bản 3.x của Apache Commons HttpClient, có thể thực hiện yêu cầu POST nhiều biểu mẫu/dữ liệu biểu mẫu (an example from 2004). Rất tiếc, điều này không thể thực hiện được nữa trong version 4.0 of HttpClient.Làm cách nào để tạo yêu cầu POST nhiều biểu mẫu/dữ liệu biểu mẫu bằng Java?

Đối với hoạt động chính "HTTP" của chúng tôi, multipart có phần là ngoài phạm vi. Chúng tôi muốn sử dụng mã nhiều phần được duy trì bởi một số dự án khác mà nó nằm trong phạm vi nhưng tôi không biết bất kỳ điều gì. Chúng tôi đã cố gắng di chuyển mã nhiều phần sang commons-codec một vài năm trước đây, nhưng tôi đã không cất cánh ở đó. Oleg gần đây đã đề cập đến một dự án khác có mã phân tích nhiều phần và có thể quan tâm đến trong mã định dạng nhiều phần của chúng tôi. Tôi không biết trạng thái hiện tại về điều đó. (http://www.nabble.com/multipart-form-data-in-4.0-td14224819.html)

Có ai biết về bất kỳ thư viện Java nào cho phép tôi viết một ứng dụng HTTP có thể thực hiện yêu cầu POST nhiều biểu mẫu dữ liệu không?

Thông tin cơ bản: Tôi muốn sử dụng số Remote API of Zoho Writer.

+0

xem thêm - http://bayou.io/release/1.0/docs/http/Http_Client.html – ZhongYu

Trả lời

133

Chúng tôi sử dụng HttpClient 4.x để tạo bài đăng nhiều phần.

CẬP NHẬT: Kể từ HttpClient 4.3, một số lớp học không được dùng nữa. Đây là mã với API mới:

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(); 

Dưới đây là đoạn ban đầu của mã với phản 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(); 
+60

Ah, những thứ nhiều phần dữ liệu đã được chuyển đến org.apache.httpcomponents-httpmime-4.0 ! Có thể được đề cập ở đâu đó:/ –

+0

Tôi đã thử mã cập nhật của bạn hoạt động tốt với các tệp nhỏ nhưng không hoạt động với các tệp lớn. Bạn có thể giúp tôi với [câu hỏi này] (http://stackoverflow.com/questions/25850077/how-to-upload-large-files-by-multipart-request-in-java) – abi1964

+0

Xin chào ZZ, tôi đã thực hiện sự thay đổi trên trong mã của tôi, tuy nhiên, tôi đang đối mặt với một vấn đề mới ngay bây giờ - điểm cuối REST của tôi không chấp nhận yêu cầu. Nó mong đợi các tham số sau: ~ @ PathVariable String cuối cùng, @RequestParam ("hình ảnh") hình ảnh MultipartFile cuối cùng, @RequestParam ("l") Chuỗi cuối cùng l, @RequestParam ("lo") final String lo, @RequestParam ("bac") cuối cùng Chuỗi bac, @RequestParam ("cac") Chuỗi cuối cùng cac, @RequestParam ("m") Chuỗi cuối cùng m ... Trước đây, yêu cầu đã được chấp nhận. Nhưng bây giờ tôi nhận được 500 lỗi. Bất kỳ ý tưởng nào tại sao điều này có thể xảy ra? – Logan

2

httpcomponents-client-4.0.1 làm việc cho tôi. Tuy nhiên, tôi phải thêm bình bên ngoài apache-mime4j-0.6.jar (org.apache.james.mime4j) nếu không, reqEntity.addPart("bin", bin); sẽ không biên dịch. Bây giờ nó hoạt động như sự quyến rũ.

34

Đây là những phụ thuộc Maven mà tôi có.

Java Code:

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 trong 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> 
+4

+1 để thêm phụ thuộc Maven. Tiết kiệm thời gian! –

+1

bạn cũng cần httpcore, ít nhất là 4.2, đối với lớp 'HttpEntity' – alalonde

4

Bạn cũng có thể sử dụng REST Assured được xây dựng dựa trên HTTP Client. Nó rất đơn giản:

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

Nó sẽ giả sử một tên điều khiển được gọi là" tệp ". Nếu bạn có một tên điều khiển khác thì bạn cần phải xác định nó: 'multiPart (" controlName ", tệp mới ("/somedir/file.bin "))', xem https://github.com/rest-assured/rest -assured/wiki/Usage # multi-part-form-data – asmaier

14

Nếu kích thước của vấn đề lọ (ví dụ trong trường hợp của applet), người ta có thể cũng sử dụng trực tiếp httpmime với java.net.HttpURLConnection thay vì 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(); 
... 

phụ thuộc vào pom.xml:

<dependency> 
    <groupId>org.apache.httpcomponents</groupId> 
    <artifactId>httpmime</artifactId> 
    <version>4.2.4</version> 
</dependency> 
+0

FileBody có nguồn gốc từ đâu? Có cách nào (dễ) để không sử dụng apace.httpcomponents? –

4

Sử dụng mã này để tải lên hình ảnh hoặc bất kỳ tệp nào khác lên máy chủ bằng cách sử dụng tính năng đa phần.

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(); 
     } 
    } 

} 

yêu cầu tệp bên dưới tải lên.

thư viện là 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 được trong classpath.

0

Chúng tôi có thực thi java thuần túy về gửi biểu mẫu nhiều phần mà không sử dụng bất kỳ phụ thuộc bên ngoài hoặc thư viện nào ngoài jdk. Tham khảo 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); 
    } 
} 
Các vấn đề liên quan