2012-03-13 38 views
14

Điều tôi muốn làm là gửi biểu mẫu web từ ứng dụng java. Biểu mẫu tôi cần điền vào nằm ở đây: http://cando-dna-origami.org/Http POST bằng Java (với tải lên tệp)

Khi biểu mẫu được gửi, máy chủ gửi email xác nhận đến địa chỉ email đã cho, hiện tại tôi chỉ đang kiểm tra thủ công. Tôi đã thử điền vào biểu mẫu theo cách thủ công và email được gửi đi tốt. (Cũng cần lưu ý rằng khi biểu mẫu được điền không chính xác, trang chỉ làm mới và không đưa ra bất kỳ phản hồi nào).

Tôi chưa bao giờ làm bất cứ điều gì với http trước đây, nhưng tôi nhìn xung quanh một lúc, và đã đưa ra đoạn mã sau, mà là vụ phải gửi một yêu cầu POST đến server:

String data = "name=M+V&affiliation=Company&email=" 
      + URLEncoder.encode("[email protected]", "UTF-8") 
      + "&axialRise=0.34&helixDiameter=2.25&axialStiffness=1100&bendingStiffness=230" + 
      "&torsionalStiffness=460&nickStiffness=0.01&resolution=course&jsonUpload=" 
      + URLEncoder.encode("C:/Users/Marjie/Downloads/twisted_DNA_bundles/monotwist.L1.v1.json", 
      "UTF-8") + "&type=square"; 

    URL page = new URL("http://cando-dna-origami.org/"); 
    HttpURLConnection con = (HttpURLConnection) page.openConnection(); 

    con.setDoOutput(true); 
    con.setRequestMethod("POST"); 
    con.connect(); 

    OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream()); 
    out.write(data); 
    out.flush(); 

    System.out.println(con.getResponseCode()); 
    System.out.println(con.getResponseMessage()); 

    out.close(); 
    con.disconnect(); 

Tuy nhiên , khi nó chạy nó không xuất hiện để làm bất cứ điều gì - đó là, tôi không nhận được bất kỳ email, mặc dù chương trình không in "200 OK" để System.out, mà dường như chỉ ra rằng một cái gì đó đã nhận được từ máy chủ, mặc dù tôi không chắc nó có ý nghĩa gì. Tôi nghĩ rằng vấn đề có thể là trong quá trình tải lên tệp, vì tôi không chắc liệu loại dữ liệu đó có yêu cầu định dạng khác hay không.

Đây có phải là cách chính xác để gửi yêu cầu POST bằng Java không? Tôi có cần phải làm gì đó khác để tải tệp lên không? Cảm ơn!


Sau khi đọc bài của Adam, tôi sử dụng Apache HttpClient và viết đoạn mã sau:

List<NameValuePair> params = new ArrayList<NameValuePair>(); 
    params.add(new BasicNameValuePair("type", "square")); 
    //... add more parameters 

    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, HTTP.UTF_8); 

    HttpPost post = new HttpPost("http://cando-dna-origami.org/"); 
    post.setEntity(entity); 

    HttpResponse response = new DefaultHttpClient().execute(post); 
    post = new HttpPost("http://cando-dna-origami.org/"); 

    post.setEntity(new FileEntity(new File("C:/Users/Marjie/Downloads/twisted_DNA_bundles/monotwist.L1.v1.json"), "text/plain; charset=\"UTF-8\"")); 
    HttpResponse responseTwo = new DefaultHttpClient().execute(post); 

Tuy nhiên, nó vẫn có vẻ không thể làm việc; một lần nữa, tôi đã không chắc chắn làm thế nào các tập tin tải lên phù hợp với hình thức, vì vậy tôi đã cố gắng chỉ gửi hai yêu cầu POST riêng biệt, một với các hình thức và một với các dữ liệu khác. Tôi vẫn đang tìm cách kết hợp chúng thành một yêu cầu; không ai biết điều gì về điều này?

Trả lời

17

Có thể bạn nên sử dụng một cái gì đó như Apache HttpClient, mà bạn có thể xây dựng một yêu cầu POST theo cách lập trình.

HttpClient httpclient = new DefaultHttpClient(); 
HttpPost httppost = new HttpPost("http://.../whatever"); 

List <NameValuePair> params = new ArrayList<NameValuePair>(); 
params.add(new BasicNameValuePair("param1", "value1")); 
params.add(new BasicNameValuePair("param2", "value2")); 
... 

httpost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); 

HttpResponse response = httpclient.execute(httppost); 

Nếu bạn cần phải tải lên một tập tin cùng với biểu mẫu, bạn sẽ cần phải sử dụng một MultipartEntity thay vì:

MultipartEntity reqEntity = new MultipartEntity(); 
reqEntity.addPart("someParam", "someValue"); 
reqEntity.addPart("someFile", new FileBody("/some/file")); 
.... 

httpost.setEntity(reqEntity); 

Có một số chương trình mẫu trên trên their site. "Mẫu đăng nhập dựa trên" và "thực thể yêu cầu được mã hóa Multipart" là các ví dụ tốt để bắt đầu.

Cũng có thể đáng thử nghiệm kết nối của bạn và xem dữ liệu mạng cơ bản để xem điều gì đang xảy ra. Một cái gì đó như Firebug sẽ cho bạn thấy chính xác những gì đang xảy ra trong trình duyệt của bạn, và bạn có thể bật đăng nhập HttpClient để xem tất cả dữ liệu được trao đổi trong chương trình của bạn. Ngoài ra, bạn có thể sử dụng một cái gì đó như Wireshark hoặc Fiddler để xem lưu lượng truy cập mạng của bạn trong thời gian thực. Điều này có thể cung cấp cho bạn một ý tưởng tốt hơn về chính xác những gì trình duyệt của bạn đang làm, so với những gì chương trình của bạn đang làm.

+0

Cảm ơn lời khuyên của bạn! Tôi đã tải xuống Apache HttpClient và đã viết một đoạn mã khác bằng cách sử dụng thay vào đó; tiếc là nó vẫn không có vẻ là làm bất cứ điều gì. Vấn đề vẫn là tôi không chắc chắn làm thế nào để kết hợp các hình thức và tải lên tập tin. Xem ở trên – Reyan

+0

Vì vậy, tôi khuyên bạn hãy xem dữ liệu cơ bản đi qua kết nối HTTP (đoạn cuối cùng của câu trả lời của tôi), như vậy sẽ làm rõ sự khác biệt giữa việc sử dụng trình duyệt (đang hoạt động) và chương trình của bạn đang hoạt động) –

+0

Bây giờ tôi hiểu. Tôi đã cập nhật câu trả lời với thông tin về cách thêm tệp tải lên. –

1

Tôi hiện đang viết một máy chủ web nhỏ và tôi đã kiểm tra ứng dụng khách yêu cầu của bạn. Máy chủ của tôi nhận được yêu cầu sau:

User-Agent: Java/1.6.0_20 
Host: localhost:1700 
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 
Connection: keep-alive 
Content-type: application/x-www-form-urlencoded 
Content-Length: 287 
name=M+V&affiliation=Company&email=m.v%40gmail.com&axialRise=0.34&helixDiameter=2.25&axialStiffness=1100&bendingStiffness=230&torsionalStiffness=460&nickStiffness=0.01&resolution=course&jsonUpload=C%3A%2FUsers%2FMarjie%2FDownloads%2Ftwisted_DNA_bundles%2Fmonotwist.L1.v1.json&type=square 

Bạn nên kiểm tra định dạng dữ liệu POST bạn đang gửi, có thể máy chủ không xử lý như bạn mong đợi.

+0

Cảm ơn câu trả lời của bạn và để kiểm tra mã! Ý của bạn chính xác là gì bởi "dữ liệu POST" mà tôi đang gửi? Bạn có nghĩa là chỉ có dữ liệu biểu mẫu, hoặc cũng là dữ liệu khách hàng và kết nối? Tôi rất tiếc phải nói, tôi không hiểu ý nghĩa của thông tin mà bạn đã đăng trong hộp mã. Có điều gì sai với cài đặt kết nối không? – Reyan

+0

Tôi đã đề cập đến biến "dữ liệu" với dữ liệu biểu mẫu. Dữ liệu từ hộp đại diện cho tiêu đề và nội dung mà máy chủ nhận được. – Alex

2

Bạn chắc chắn nên sử dụng apaches HTTPClient cho công việc đó! Nó làm cho cuộc sống dễ dàng hơn nhiều. Dưới đây là một ví dụ làm thế nào để tải lên một tập tin với apache HttpClient.

byte[] data = outStream.toByteArray() 
HttpClient client = new DefaultHttpClient(); 
HttpPost httpPost = new HttpPost("http://localhost:8080/YourResource"); 

ByteArrayBody byteArrayBody = new ByteArrayBody(data, "application/json", "some.json"); 
MultipartEntity multipartEntity = new MultipartEntity(); 
multipartEntity.addPart("upload", byteArrayBody); 
httpPost.setEntity(multipartEntity); 

HttpResponse response = client.execute(httpPost); 
Reader reader = new InputStreamReader(response.getEntity().getContent()); 

Hãy cho tôi biết nếu bạn có thêm câu hỏi.

0

Dưới đây là một ví dụ tôi đã làm việc sử dụng apache httpclient. Ngoài ra, đừng quên thêm những phụ thuộc:

<dependency> 
     <groupId>org.apache.httpcomponents</groupId> 
     <artifactId>httpclient</artifactId> 
     <version>4.4.1</version> 
    </dependency> 


    <dependency> 
     <groupId>org.apache.httpcomponents</groupId> 
     <artifactId>httpmime</artifactId> 
     <version>4.4.1</version> 
    </dependency> 

Mã:. HttpClient httpclient = HttpClientBuilder.create() xây dựng();

HttpPost httppost = new HttpPost(DataSources.TORRENT_UPLOAD_URL); 

MultipartEntityBuilder builder = MultipartEntityBuilder.create(); 
      builder.addPart("a_field_name", new FileBody(torrentFile)); 

HttpEntity entity = builder.build(); 

httppost.setEntity(entity); 

HttpResponse response = httpclient.execute(httppost); 
1

Như hầu hết các mã yêu cầu Java HTTP POST gợi ra không có hoạt động, tôi quyết định cung cấp cho bạn mã hoạt động đầy đủ của tôi mà tôi chắc chắn bạn sẽ tìm thấy hữu ích để tạo ra bất kỳ yêu cầu POST dựa trên nền Java trong tương lai.

Yêu cầu POST này là multipart nhập để cho phép gửi/tải tệp lên máy chủ.

yêu cầu Multipart bao gồm một tiêu đề chính và một chuỗi phân cách gọi ranh giới để nói với nhau một phần từ khác (tách này sẽ đến trong luồng với "-" (hai dấu gạch ngang) chuỗi trước đó, và từng bộ phận có tiêu đề nhỏ riêng của mình để nói với loại của nó và một số chi tiết meta-data.

nhiệm vụ của tôi là tạo ra một tập tin PDF sử dụng một số dịch vụ trực tuyến, nhưng tất cả các ví dụ POST nhiều phần dữ liệu chỉ không làm các trick ...

Tôi cần đóng gói một tài liệu HTML cùng với các bức ảnh, tệp JS và CSS trong tệp ZIP/TAR, tải tệp đó lên dịch vụ chuyển đổi html2pdf trực tuyến và nhận kết quả dưới dạng tài liệu PDF ument trở lại với tôi như là phản ứng (stream) từ dịch vụ.

Dịch vụ hiện tại tôi đã kiểm tra bằng mã sau đây là: Htmlpdfapi.com nhưng tôi chắc chắn rằng với các điều chỉnh nhỏ, bạn sẽ có thể sử dụng dịch vụ này với bất kỳ dịch vụ nào khác.

Các gọi phương thức (đối với dịch vụ đó) trông giống như sau: [class instance name].sendPOSTRequest("http://htmlpdfapi.com/api/v1/pdf", "Token 6hr4-AmqZDrFVjAcJGykjYyXfwG1wER4", "/home/user/project/srv/files/example.zip", "result.pdf");

Đây là mã của tôi đã được kiểm tra và 100% công trình:

public void sendPOSTRequest(String url, String authData, String attachmentFilePath, String outputFilePathName) 
{ 
    String charset = "UTF-8"; 
    File binaryFile = new File(attachmentFilePath); 
    String boundary = "------------------------" + Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value. 
    String CRLF = "\r\n"; // Line separator required by multipart/form-data. 
    int responseCode = 0; 

    try 
    { 
     //Set POST general headers along with the boundary string (the seperator string of each part) 
     URLConnection connection = new URL(url).openConnection(); 
     connection.setDoOutput(true); 
     connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); 
     connection.addRequestProperty("User-Agent", "CheckpaySrv/1.0.0"); 
     connection.addRequestProperty("Accept", "*/*"); 
     connection.addRequestProperty("Authentication", authData); 

     OutputStream output = connection.getOutputStream(); 
     PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true); 

     // Send binary file - part 
     // Part header 
     writer.append("--" + boundary).append(CRLF); 
     writer.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF); 
     writer.append("Content-Type: application/octet-stream").append(CRLF);// + URLConnection.guessContentTypeFromName(binaryFile.getName())).append(CRLF); 
     writer.append(CRLF).flush(); 

     // File data 
     Files.copy(binaryFile.toPath(), output); 
     output.flush(); 

     // End of multipart/form-data. 
     writer.append(CRLF).append("--" + boundary + "--").flush(); 

     responseCode = ((HttpURLConnection) connection).getResponseCode(); 


     if(responseCode !=200) //We operate only on HTTP code 200 
      return; 

     InputStream Instream = ((HttpURLConnection) connection).getInputStream(); 

     // Write PDF file 
     BufferedInputStream BISin = new BufferedInputStream(Instream); 
     FileOutputStream FOSfile = new FileOutputStream(outputFilePathName); 
     BufferedOutputStream out = new BufferedOutputStream(FOSfile); 

     int i; 
     while ((i = BISin.read()) != -1) { 
      out.write(i); 
     } 

     // Cleanup 
     out.flush(); 
     out.close(); 


    } 
    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 

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