3

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:

  1. Why did adding "Content-Type" break my request? Shouldn't HttpClient add boundary elements to content-type defined by me?

  2. Should I explicity set "Content-Type" to my request or let the library handle it?

  3. If I can set Content-Type explicity could you provide a code snippet?

  4. 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

How can I See the content of a MultipartForm request?

2 Answers 2

2

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:

As with all multipart MIME types, each part has an optional "Content-Type", which defaults to text/plain.

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:

If multiple files are to be returned as the result of a single form entry, they should be represented as a "multipart/mixed" part embedded within the "multipart/form-data".

Hope this helps.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the link - after I read it and do few tests with HttpClient i found what I was doing wrong: when setting "Content-Type" i need to provide boundary (post.addHeader("Content-Type", "multipart/form-data; boundary=randomBoundaryNotInAnyOfParts") also i need to provide SAME boundary to MultipartEntity or else HttpClient will insert between parts his own random boundary. Tnx for pointing me the right way :).
I am in the same situation but didn't understand what to do. I was hoping that the MultipartEntity would tell the HttpPost object that it is multipart, form data and have some boundary, and I wouldnt set content type by myself. I didn't quite get how to provide boundaries to the entities - the MultipartEntity doesn't have a method like setBoundary. Or, how to get that randomly generated boundary to specify it in addHeader by myself - no getBoundary methor either...
0

to fedd/ the class which inserts randomly generated boundary is HttpClient, not HttpPost. so you should look at methods for HttpClient

1 Comment

sorry, i was to add comment for fedd, but clicked wrong button :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.