2014-04-22 18 views
5

Tôi đang sử dụng Apache HttpComponents v4.3.3 (maven httpclient và httpmime). Tôi cần tải lên tệp có một số siêu dữ liệu. Lệnh curl, hoạt động, trông giống như sau.làm cách nào để tạo và đăng yêu cầu http nhiều phần/hỗn hợp bằng cách sử dụng Apache HttpComponentst?

curl -k -i -H "Loại nội dung: multipart/mixed" -X POST --form 'field1 = val1' --form 'field2 = val2' --form 'file = @ somefile. zip; type = application/zip 'https://www.some.domain/

Tôi đã thử bắt chước bài đăng này như sau.

HttpEntity entity = MultiPartEntityBuilder 
.create() 
.addPart("field1",new StringBody("val1",ContentType.TEXT_PLAIN)) 
.addPart("field2",new StringBody("val2",ContentType.TEXT_PLAIN)) 
.addPart("file", new FileBody(new File("somefile.zip"), ContentType.create("application/zip")) 
.build(); 
HttpPost post = new HttpPost("https://www.some.domain"); 
post.addHeader("Content-Type", "multipart/mixed"); 

Tuy nhiên, sau khi tôi sử dụng HttpClient để thực hiện HttpPost, tôi nhận được ngoại lệ sau (mã máy chủ cũng được Java chạy trên Jetty).

org.apache.commons.fileupload.FileUploadException: yêu cầu đã bị từ chối vì không có ranh giới nhiều phần dữ liệu đã được tìm thấy

Khi tôi thêm một dấu vết cuộn tròn

curl - trace - -k -i -H "Kiểu nội dung: multipart/mixed" -X POST - form 'field1 = val1' --form 'field2 = val2' --form '[email protected]; type = ứng dụng/zip 'https://www.some.domain/

Tôi thấy rằng các cặp trường/giá trị biểu mẫu được đặt làm tiêu đề HTTP.

Nội dung-Bố trí: biểu mẫu-dữ liệu; name = field1 ... value1

Bất kỳ ý tưởng nào về những gì tôi đang làm sai ở đây? Bất kỳ trợ giúp được đánh giá cao.

Trả lời

7

Tôi đã sửa đổi một chút và thực hiện hai việc để mã hoạt động.

  • không còn sử dụng addPart (...)
  • không còn thiết lập Content-Type tiêu đề

Sau đây là đoạn sửa đổi đó là làm việc trong trường hợp có ai quan tâm.

HttpEntity entity = MultipartEntityBuilder 
.create() 
.addTextBody("field1","val1") 
.addTextBody("field2","val2") 
.addBinaryBody("file", new File("somefile.zip"),ContentType.create("application/zip"),"somefile.zip") 
.build(); 
HttpPost post = new HttpPost("https://www.some.domain"); 
post.setEntity(entity); 

Tôi cũng đặt HttpComponents thành chế độ gỡ lỗi.

 
-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog 
-Dorg.apache.commons.logging.simplelog.showdatetime=true 
-Dorg.apache.commons.logging.simplelog.log.org.apache.http=DEBUG 

Nó chỉ ra rằng mỗi phần giờ có một đường biên. Thậm chí tốt hơn, Content-Type và ranh giới được tạo tự động.

Loại nội dung: multipart/form-data; ranh giới = 5ejxpaJqXwk2n_3IVZagQ1U0_J_X9MdGvst9n2Tc

+0

Không biết tại sao bạn không nhận được bất kỳ phiếu bầu nào - đây là giải pháp cho multipart trên Android! Các công cụ khác mà tôi tìm thấy đã làm tất cả theo cách thủ công và khá cồng kềnh .... – Lonzak

+0

Nhưng đây không phải là đa phần/hỗn hợp. Dường như có hàng trăm câu trả lời làm thế nào để làm điều đó với multipart/form-data. – unwichtich

1

Đây mã đầy đủ của tôi có trụ sở tại phản ứng cuối cùng, nhưng hơi khác nhau, tôi đã có lỗi tương tự nhưng hiện đang làm việc (nhờ Jane!):

public String sendMyFile(String p_file, String p_dni, String p_born_date) throws Exception { 

    HttpClient httpclient = HttpClientBuilder.create().build(); 

    HttpPost httppost = new HttpPost("http://localhost:2389/TESTME_WITH_NETCAT"); 

    /* Campos del formulario del POST que queremos hacer */ 
    File  fileIN = new File(p_file); 

    /* Construimos la llamada */ 
    MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create(); 

    reqEntity 
      .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) 
      .addBinaryBody ("p_file"    , fileIN) 
      .addTextBody ("p_dni"    , p_dni) 
      .addTextBody ("p_born_date" , p_born_date); 

    httppost.setEntity(reqEntity.build()); 

    System.out.println("executing request " + httppost.getRequestLine()); 

    HttpResponse response = httpclient.execute(httppost); 

    System.out.println("1 ----------------------------------------"); 
    System.out.println(response.getStatusLine()); 
    System.out.println("2 ----------------------------------------"); 
    System.out.println(EntityUtils.toString(response.getEntity())); 
    System.out.println("3 ----------------------------------------"); 

    HttpEntity resEntity = response.getEntity(); 

    if (resEntity != null) { 
     System.out.println("Response content length: " + resEntity.getContentLength()); 
    } 

    return "OK"; 
} 
+1

Chào mừng bạn đến với Stack Overflow! Mặc dù đoạn mã này có thể giải quyết được câu hỏi, [bao gồm cả sự bùng nổ] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời các câu hỏi cho người đọc trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn. – gunr2171

Các vấn đề liên quan