使用HttpClient4在上传文件中设置标题“Content-Type”时出现问题

我正在尝试上传文件(或多个文件)到我的servlet,它使用Apache文件上传来处理和获取后期文件。

当我使用以下代码时,一切顺利,文件发送和接收。

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())); 

但是当我尝试将我自己的“Content-Type”设置为推荐的(或者只有Apache文件上传库接受的)并带有上传文件时:

 post.addHeader("Content-Type", "multipart/form-data"); 

我的servlet没有得到任何文件并抛出一个exeption:

 org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.(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) 

我知道带有上传文件的POST请求在请求中不应包含边界“元素”以确定上传的字节块的顺序,但我认为HttpClient会将所有需要的信息添加到我的请求中(类似于我不知道的时候) t指定内容类型)。

我的问题是:

  1. 为什么添加“内容类型”会破坏我的请求? HttpClient不应该将边界元素添加到我定义的内容类型中吗?

  2. 我应该明确地将“Content-Type”设置为我的请求还是让库处理它?

  3. 如果我可以设置Content-Type明确,你可以提供一个代码片段吗?

  4. 如果我可以明确设置内容类型,为什么我应该使用并且更喜欢“multipart / form-data”到“application / x-www-form-urlencoded”来发布到某些表单?

PS:我发现了一些相关的问题,但没有解决我的问题:

带有commons-upload和httpcomponent客户端的ContentType问题

如何查看MultipartForm请求的内容?

如果您有表单数据enctype,则必须遵循RFC 2388中指定的规则。 多部分消息中的数据被视为实体,因此每个实体必须具有标题(具有Content-DispositionContent-Type等)和边界。

至于回答问题1,RFC规定:

与所有多部分MIME类型一样,每个部分都有一个可选的“Content-Type”,默认为text / plain。

对于2),如上所述,每个多部分消息必须有一个标题,因此您必须指定您的Content-Type(如果您没有完全使用HttpClient库特性)。

对于3)和4)RFC状态:

如果作为单个表单条目的结果将返回多个文件,则它们应表示为嵌入在“multipart / form-data”中的“multipart / mixed”部分。

希望这可以帮助。

to fedd /插入随机生成的边界的类是HttpClient,而不是HttpPost。 所以你应该看看HttpClient的方法