简体   繁体   中英

Problem with setting header “Content-Type” in uploading file with HttpClient4

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?

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM