What I want to do is submit a web form from a java application. The form I need to fill out is located here: http://cando-dna-origami.org/
When the form is submitte
You should definitively use apaches HTTPClient for that job! It makes life much easier. Here is an example how to upload a file with 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());
Let me know if you have further questions.
You would probably be better off using something like Apache HttpClient, with which you can build up a POST
request programatically.
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);
If you need to upload a file along with your form, you will need to use a MultipartEntity
instead:
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("someParam", "someValue");
reqEntity.addPart("someFile", new FileBody("/some/file"));
....
httpost.setEntity(reqEntity);
There are some sample programs over on their site. The "Form based logon" and "Multipart encoded request entity" are good examples to start from.
It may also be worthwhile testing out your connections and taking a look at the underlying network data to see what is happening. Something like Firebug will let you see exactly what is happening in your browser, and you can turn up the HttpClient logging to see all of the data exchanged in your program. Alternatively, you can use something like Wireshark or Fiddler to watch your network traffic in real-time. This may give you a better idea of exactly what your browser is doing, versus what your program is doing.
I am currently writing a small web server, and I tested your request client. My server is receiving the following request:
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
You should check the format of the POST data you are sending, most probably it is not processed by the server as you would expect.
As most of the suggested Java HTTP POST request code out there is not operational, I decided to give you my fully operational code that I'm sure you'll find helpful to create any Java-based POST request in the future.
This POST request is of multipart
type to allow sending/uploading a file to the server.
Multipart request consist of a main header and a separator string called boundary to tell each part from the other (this separator will come in the stream with "--" (two dashes) string before it, and each part has its own small header to tell its type and some more meta-data.
My task was to create a PDF file using some online services but all the multipart POST examples just didn't do the trick...
I needed to pack an HTML document along with its pics, JS and CSS files in a ZIP/TAR file, upload it to an online html2pdf conversion service and get the result as a PDF document back to me as the response (stream) from the service.
The current service I've checked the using following code is: Htmlpdfapi.com but I'm sure that with minor adjustments you'll be able to use it with any other service.
The method call (for that service) looks something like:
[class instance name].sendPOSTRequest("http://htmlpdfapi.com/api/v1/pdf", "Token 6hr4-AmqZDrFVjAcJGykjYyXfwG1wER4", "/home/user/project/srv/files/example.zip", "result.pdf");
Here is my code that was checked and 100% works:
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();
}
}
Here's an example I got working that uses apache httpclient. Also, don't forget to add these dependencies:
<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>
The code:
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);