2012-03-13 261 views
14

我想要做的是从java应用程序提交一个web表单。我需要填写的表格位于:http://cando-dna-origami.org/Java中的HTTP POST(带文件上传)

表单提交后,服务器会发送一封确认电子邮件给给定的电子邮件地址,现在我只需手工检查。我试过手动填写表单,并且电子邮件发送得很好。 (还应该注意的是,当表单填写不正确时,页面会刷新并且不会给出任何反馈)。

我从来没有做过以http任何事情之前,但我左顾右盼了一会儿,用下面的代码,这是应该发送POST请求到服务器上来:

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

然而,它运行时似乎没有做任何事情 - 也就是说,我没有收到任何电子邮件,尽管程序确实向System.out打印了“200 OK”,这似乎表明从服务器收到了某些东西,虽然我不确定它究竟意味着什么。我认为问题可能出现在文件上传中,因为我不确定该数据类型是否需要不同的格式。

这是发送使用Java POST请求以正确的方式?我需要为文件上传做些不同的事情吗?谢谢!


阅读亚当的文章后,我使用的Apache的HttpClient和写了下面的代码:

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

但是,它仍然似乎并不奏效;再次,我不确定上传的文件是如何适应表单的,所以我试着发送两个单独的POST请求,一个是表单,一个是其他数据。我仍在寻找一种将这些结合为一个请求的方法;有人知道这件事吗?

回答

17

你可能会更喜欢使用类似Apache HttpClient的东西,通过它你可以编程方式建立一个POST请求。

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

如果你需要上传文件的形式一起,你将需要使用MultipartEntity代替:

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

httpost.setEntity(reqEntity); 

有一些示例程序在上their site。 “基于表单的登录”和“多部分编码的请求实体”是很好的例子。

这也可能是值得的测试出你的连接,并考虑看看底层的网络数据,看看发生了什么。像Firebug这样的东西可以让你看到你的浏览器到底发生了什么,你可以打开HttpClient日志来查看程序中交换的所有数据。或者,您可以使用Wireshark或Fiddler等实时查看您的网络流量。这可以让你更清楚地知道你的浏览器正在做什么,而不是你的程序在做什么。

+0

谢谢你的建议!我下载了Apache HttpClient并使用它编写了一段不同的代码;不幸的是,它似乎还没有做任何事情。问题仍然是我不确定如何组合表单和文件上传。见上面 – Reyan 2012-03-13 22:10:03

+0

所以我建议你看看HTTP连接(我的答案的最后一段)的基础数据,因为这将阐明浏览器使用(正在工作)和你的程序(它是不工作) – 2012-03-14 01:58:06

+0

现在我明白了。我已经更新了有关添加文件上传的信息。 – 2012-03-14 12:50:52

1

我目前正在写一个小型的web服务器,我测试你的要求的客户。我的服务器接收以下请求:

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 

您应该检查您发送POST数据,最有可能它不是由服务器处理如你所期望的格式。

+0

感谢您的回答,并测试代码!您发送的“POST数据”是什么意思?你的意思只是表单数据,或者客户端和连接数据?我很抱歉地说,我不明白您在代码框中发布的信息的重要性。连接设置有问题吗? – Reyan 2012-03-13 22:06:10

+0

我指的是具有表单数据的“数据”变量。框中的数据表示服务器收到的标题和内容。 – Alex 2012-03-13 22:17:03

2

你应该明确地使用apaches HTTPClient那个工作!它使生活变得更容易。这里是一个例子,如何使用apaches 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()); 

让我知道你是否还有其他问题。

0

这是我使用apache httpclient工作的一个例子。另外,不要忘了添加这些依赖关系:

<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> 

代码: 的HttpClient HttpClient的= HttpClientBuilder.create()建();

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

由于大部分建议的Java HTTP POST请求的代码在那里不工作,我决定给你我的,我敢肯定你会发现有助于创造任何基于Java的POST请求完全运行代码在将来。

该POST请求的类型为multipart,允许发送/上传文件到服务器。

多部分请求由一个主标头和称为边界从其他告诉每个部分的隔板串(该分离器将要与该流“ - ”(两个短划线)字符串之前它,并且每个部分有自己的小头,以告诉它的类型和一些更多的元数据。

我的任务是使用一些在线服务创建PDF文件,但所有的多部分POST示例只是没有办法...

我需要将HTML文档及其图片,JS和CSS文件打包到ZIP/TAR文件中,将其上传到在线html2pdf转换服务并将结果作为PDF文档作为来自服务的响应(流)返回给我。

我使用以下代码检查过的当前服务是:Htmlpdfapi.com但我相信只需稍作调整,您就可以将其用于任何其他服务。

方法调用(该服务)看起来像: [class instance name].sendPOSTRequest("http://htmlpdfapi.com/api/v1/pdf", "Token 6hr4-AmqZDrFVjAcJGykjYyXfwG1wER4", "/home/user/project/srv/files/example.zip", "result.pdf");

这里是我的代码的确认,以及100%的作品:

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

} 
相关问题