I'm trying to a upload file (or multiple files) to my servlet, which is using Apache file-upload to handle and get post-ed files.
All is going well and the file is send and recieved, when I use the following code.
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://myservice.com/servlet");
MultipartEntity entity2 = new MultipartEntity();
FileBody fileBody = new FileBody(new File("C:/docOut.pdf"));
entity2.addPart("file", fileBody);
post.setEntity(entity2);
HttpResponse httpResponse = client.execute(post);
System.out.println(EntityUtils.toString(httpResponse.getEntity()));
But when I try to set my own "Content-Type" to recommended one (or the one only accepted with the Apache file-upload library) with uploading file:
post.addHeader("Content-Type", "multipart/form-data");
My servlet doesn't get any of files and throws an exeption:
org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:931)
at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:349)
at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
at com.myservice.server.filerep.action.FileUploadFormAction.execute(FileUploadFormAction.java:54)
at com.myservice.server.filerep.web.FileRepServlet.doGet(FileRepServlet.java:34)
at com.myservice.server.filerep.web.FileRepServlet.doPost(FileRepServlet.java:41)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
I'm aware that POST requests with the uploading file shouldn't contain boundary "elements" in request to determine the order of uploaded byte chunks, but I thought HttpClient will add all the needed information to my request (similar as when I don't specify content-type).
My questions are:
Why did adding "Content-Type" break my request? Shouldn't HttpClient add boundary elements to content-type defined by me?
Should I explicity set "Content-Type" to my request or let the library handle it?
If I can set
Content-Type
explicity could you provide a code snippet?If I can explicity set Content-Type why should I use and prefer "multipart/form-data" to "application/x-www-form-urlencoded" when it comes to POSTing to some forms?
PS: I found somehow related questions, but not addressing my problem:
ContentType issue with commons-upload and httpcomponent client
to fedd/ the class which inserts randomly generated boundary is HttpClient, not HttpPost. so you should look at methods for HttpClient
If you have form data enctype, you must follow the rules as specified in RFC 2388. Data in multipart message are treated as entity so each entity must have a header (with
Content-Disposition
,Content-Type
, etc.) and a boundary.As to answer question 1, the RFC states:
For 2), As mentioned, every multipart message must have an header, so you have to specify your Content-Type (if you're not fully using HttpClient library features).
For 3) and 4) RFC states:
Hope this helps.