我想要做的是从Java应用程序提交Web表单。我需要填写的表单位于:http://cando-dna-origami.org/
提交表单后,服务器会向给出的电子邮件地址发送一封确认电子邮件,目前我只是手工检查。我已经尝试手动填写表单,电子邮件也很好。 (还应该注意的是,当表单填写不正确时,页面只会刷新并且不会给出任何反馈。)
我之前从未做过任何关于http的事情,但我环顾了一会儿,并提出了以下代码,它应该向服务器发送一个POST请求:
String data = "name=M+V&affiliation=Company&email="
+ URLEncoder.encode("m.v@gmail.com", "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请求的正确方法吗?我是否需要为文件上传执行不同的操作?谢谢!
在阅读Adam的帖子后,我使用了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请求,一个与表单,一个与其他数据。我仍然在寻找一种方法将这些组合成一个请求;有人知道这个吗?
答案 0 :(得分: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等实时监控网络流量。这可以让您更好地了解浏览器正在做什么,而不是您的程序正在做什么。
答案 1 :(得分:2)
你应该明确地使用apache HTTPClient来完成这项工作!它让生活更轻松。以下是如何使用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());
如果您还有其他问题,请与我们联系。
答案 2 :(得分: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数据的格式,很可能它不会像您期望的那样由服务器处理。
答案 3 :(得分:1)
由于大多数建议的Java HTTP POST请求代码无法运行,我决定向您提供完全可操作的代码,我确信您会发现有助于创建任何基于Java的POST请求在将来。
此POST请求为multipart
类型,允许将文件发送/上传到服务器。
多部分请求包含一个主标题和一个名为边界的分隔符字符串,用于告诉每个部分与另一个部分(此分隔符将出现在&#34流中: - &#34;(两个破折号)前面的字符串,每个部分都有自己的小标题来告诉它的类型和一些更多的元数据。
我的任务是使用一些在线服务创建PDF文件,但所有多部分POST示例都没有做到这一点......
我需要将一个HTML文档及其图片,JS和CSS文件打包到ZIP / TAR文件中,将其上传到在线html2pdf转换服务并将结果作为PDF文档作为响应返回给我(流)来自服务。
我已检查使用以下代码的当前服务是:Htmlpdfapi.com但我确信通过微小调整,您可以将其与任何其他服务一起使用。< / p>
方法调用(对于该服务)看起来像:
[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();
}
}
答案 4 :(得分: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()。build();
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);