Проблема с настройкой заголовка «Content-Type» при загрузке файла с HttpClient4 - PullRequest
3 голосов
/ 02 июня 2011

Я пытаюсь загрузить файл (или несколько файлов) в мой сервлет, который использует 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");

Мой сервлет не получает ни одного файла и выдает исключение:

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 добавит всю необходимую информацию в мой запрос (аналогично тому, когда я не указываю тип содержимого).

Myвопросы:

  1. Почему добавление «Content-Type» нарушило мой запрос?Разве HttpClient не должен добавлять граничные элементы к определенному мной типу контента?

  2. Должен ли я явно установить "Content-Type" для моего запроса или позволить библиотеке обработать его?

  3. Если я могу установить Content-Type Explicity, можете ли вы предоставить фрагмент кода?

  4. Если я могу установить Explicity Content-Type, почему я должен использовать и предпочитать "multipart / form-data "to" application / x-www-form-urlencoded ", когда речь заходит о POSTing в некоторые формы?

PS: я нашел как-то связанные вопросы, но не обращаясь кМоя проблема:

Проблема ContentType с клиентом commons-upload и httpcomponent

Как просмотреть содержимое запроса MultipartForm?

Ответы [ 2 ]

2 голосов
/ 02 июня 2011

Если у вас есть тип данных enctype, вы должны следовать правилам, указанным в RFC 2388 .Данные в составном сообщении рассматриваются как сущность, поэтому каждая сущность должна иметь заголовок (с Content-Disposition, Content-Type и т. Д.) И границу.

Что касается ответа на вопрос 1, RFC заявляет:

Как и для всех составных MIME-типов, каждая часть имеет необязательный «Content-Type», по умолчанию используется text / plain.

Для 2), как уже упоминалось, каждая составная частьсообщение должно иметь заголовок, поэтому вы должны указать свой Content-Type (если вы не используете функции библиотеки HttpClient не полностью).

для 3) и 4) RFC-состояния:

Если несколько файлов должны быть возвращены в результате одной записи формы, они должны быть представлены как «составная / смешанная» часть, встроенная в «составные / данные формы».

Надеюсь, это поможет.

0 голосов
/ 07 мая 2013

для fedd / класс, который вставляет случайно сгенерированную границу, является HttpClient, а не HttpPost. поэтому вы должны посмотреть на методы для HttpClient

...