简体   繁体   English

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

[英]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.我正在尝试将文件(或多个文件)上传到我的 servlet,它使用 Apache 文件上传来处理和获取发布的文件。

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:但是,当我尝试将自己的“Content-Type”设置为推荐的一种(或仅被 Apache 文件上传库接受的一种)并上传文件时:

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

My servlet doesn't get any of files and throws an exeption:我的 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)

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

My questions are:我的问题是:

  1. Why did adding "Content-Type" break my request?为什么添加“Content-Type”会破坏我的请求? Shouldn't HttpClient add boundary elements to content-type defined by me? HttpClient 不应该向我定义的内容类型添加边界元素吗?

  2. Should I explicity set "Content-Type" to my request or let the library handle it?我应该明确地为我的请求设置“Content-Type”还是让图书馆处理它?

  3. If I can set Content-Type explicity could you provide a code snippet?如果我可以明确设置Content-Type ,您能否提供代码片段?

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

PS: I found somehow related questions, but not addressing my problem: PS:我发现了一些相关的问题,但没有解决我的问题:

ContentType issue with commons-upload and httpcomponent client commons-upload 和 httpcomponent 客户端的 ContentType 问题

How can I See the content of a MultipartForm request? 如何查看 MultipartForm 请求的内容?

If you have form data enctype, you must follow the rules as specified in RFC 2388 .如果您有表单数据 enctype,则必须遵循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.多部分消息中的数据被视为实体,因此每个实体必须具有 header(带有Content-DispositionContent-Type等)和边界。

As to answer question 1, the RFC states:至于回答问题 1,RFC 指出:

As with all multipart MIME types, each part has an optional "Content-Type", which defaults to text/plain.与所有多部分 MIME 类型一样,每个部分都有一个可选的“Content-Type”,默认为 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).对于 2),如前所述,每条多部分消息都必须具有 header,因此您必须指定 Content-Type(如果您没有完全使用 HttpClient 库功能)。

For 3) and 4) RFC states:对于 3) 和 4) RFC 规定:

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

Hope this helps.希望这可以帮助。

to fedd/ the class which inserts randomly generated boundary is HttpClient, not HttpPost.到 fedd/ 插入随机生成边界的 class 是 HttpClient,而不是 HttpPost。 so you should look at methods for HttpClient所以你应该看看 HttpClient 的方法

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

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