繁体   English   中英

使用 HttpClient4 上传文件时设置 header “Content-Type”的问题

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

我正在尝试将文件(或多个文件)上传到我的 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 没有得到任何文件并抛出异常:

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)

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

我的问题是:

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

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

  3. 如果我可以明确设置Content-Type ,您能否提供代码片段?

  4. 如果我可以明确设置 Content-Type,为什么我应该在发布到某些 forms 时使用并更喜欢“multipart/form-data”而不是“application/x-www-form-urlencoded”?

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

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

如何查看 MultipartForm 请求的内容?

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

至于回答问题 1,RFC 指出:

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

对于 2),如前所述,每条多部分消息都必须具有 header,因此您必须指定 Content-Type(如果您没有完全使用 HttpClient 库功能)。

对于 3) 和 4) RFC 规定:

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

希望这可以帮助。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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