I am trying to upload files using Java URL class and I have found a previous question on stack-overflow which explains very well about the details, so I try to follow it. And below is my code adopted from the sniplet given in the answer.
My problem is that if I don’t make a call to one of connection.getResponseCode() or connection.getInputStream() or connection.getResponseMessage() or anything which is related to reponse from the server, the request will never be sent to server. Why do I need to do this? Or is there any way to write the data without getting the response?
P.S. I have developed a server-side uploading servlet which accepts multipart/form-data and save it to files using FileUpload. It is stable and definitely working without any problem so this is not where my problem is generated.
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.commons.io.IOUtils;
public class URLUploader {
public static void closeQuietly(Closeable... objs) {
for (Closeable closeable : objs) {
IOUtils.closeQuietly(closeable);
}
}
public static void main(String[] args) throws IOException {
File textFile = new File("D:\\file.zip");
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/upslet/upload").openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
OutputStream output = connection.getOutputStream();
PrintWriter writer = new PrintWriter(output, true);
// Send text file.
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\"file1\"; filename=\"" + textFile.getName() + "\"");
writer.println("Content-Type: application/octet-stream");
FileInputStream fin = new FileInputStream(textFile);
writer.println();
IOUtils.copy(fin, output);
writer.println();
// End of multipart/form-data.
writer.println("--" + boundary + "--");
output.flush();
closeQuietly(fin, writer, output);
// Above request will never be sent if .getInputStream() or .getResponseCode() or .getResponseMessage() does not get called.
connection.getResponseCode();
}
}
HttpURLConnection has a bunch of setters that affect the request, so it needs to know when you’re done building the request so that it can send it off. The way it does this is by waiting until you actually ask for something back from the request, like the InputStream. (This is arguably a design flaw.) This is also why the setters throw an IllegalStateException “if already connected” — once you call a getter the connection is established and it’s too late to call a setter.
You should be able to call
getInputStream()and then justclose()it without actually reading from it.