I'm trying to send an image to a website using Java HTTP POST requests.
I'm using the base code used here Upload files from Java client to a HTTP server:
This is my modification:
String urlToConnect = "http://localhost:9000/upload";
File fileToUpload = new File("C:\\Users\\joao\\Pictures\\bla.jpg");
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
URLConnection connection = new URL(urlToConnect).openConnection();
connection.setDoOutput(true); // This sets request method to POST.
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
writer = new PrintWriter(new OutputStreamWriter(connection.getOutputStream()));
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\"picture\"; filename=\"bla.jpg\"");
writer.println("Content-Type: image/jpeg");
writer.println();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileToUpload)));
for (String line; (line = reader.readLine()) != null;) {
writer.println(line);
}
} finally {
if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
}
writer.println("--" + boundary + "--");
} finally {
if (writer != null) writer.close();
}
// Connection is lazily executed whenever you request any status.
int responseCode = ((HttpURLConnection) connection).getResponseCode();
System.out.println(responseCode); // Should be 200
I get a 200 response code in the end, but the image is buggy, as in, random colors, which make me think it's an error in character encoding. I tried using UTF-8 as in the original example, but that just creates a corrupt image.
I am also 100% sure it's not a serverside problem, because I can use rest clients such as Advanced Rest Client/Postman and they can send an image with no problems.
Can you help me pinpoint what's wrong? Thank you.
Try that:
Today I run into the same issue, I wrote a little nodejs server supports just two routes, upload and download images.
Client should be a java class which sends a images payload via HTTP POST multipart/form-data standard to the server.
If you would like to know why HTTP POST multipart/form-data, please check out the answer from Ciro Santilli from this post: What does enctype='multipart/form-data' mean?
Luckily I found this nice and really good example code:
https://www.techcoil.com/blog/how-to-upload-a-file-via-a-http-multipart-request-in-java-without-using-any-external-libraries/
It shows how we can build up the payload of an multipart http body manuelly without any external lib, only little limitation from my perspective is, that it only handle a mulitpart body with one file.
Because I had no HTML page to sniff the generated POST payload, I used python to generate it and sniff it via wireshark.
Python3 code:
Just for note: if we define the parameter files from the requests lib with an dict, it generates an mulipart/form-data content. http://docs.python-requests.org/en/master/user/advanced/#post-multiple-multipart-encoded-files
Wireshark shows everything very clear and finally I ended up with this for sending java:
To get the response from the POST just read the input stream accessed via getInputStream(), code snipped in the link.
Reader/Writer classes are designed to handle text data, while images are binary. You need to interpret your files as binary:
Of course, you still need to close all opened resources.
Use HttpClient to work out this code. Its always better to use stable libraries other than handling from scratch, unless there is something to be handled in custom way.