Удобный способ синтаксического анализа входящих параметров multipart / form-data в сервлете

Есть ли удобный способ чтения и анализа данных из входящего запроса.

Например, клиент инициирует почтовый запрос

URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
    OutputStream output = connection.getOutputStream();
    writer = new PrintWriter(new OutputStreamWriter(output, charset), true); // true = autoFlush, important!
    // Send normal param.
    writer.println("--" + boundary);
    writer.println("Content-Disposition: form-data; name=\"param\"");
    writer.println("Content-Type: text/plain; charset=" + charset);
    writer.println();
    writer.println(param);

Я не могу получить параметры с помощью request.getParameter("paramName"). Следующий код

BufferedReader reader = new BufferedReader(new InputStreamReader(
    request.getInputStream()));
  StringBuilder sb = new StringBuilder();
  for (String line; (line = reader.readLine()) != null;) {
   System.out.println(line);

  }

однако отображает контент для меня

-----------------------------29772313742745
Content-Disposition: form-data; name="name"
J.Doe
-----------------------------29772313742745
Content-Disposition: form-data; name="email"
[email protected]
-----------------------------29772313742745

Как лучше всего разобрать входящий запрос? Писать свой парсер не хочу, наверное, есть готовое решение.


person atuser    schedule 26.07.2010    source источник


Ответы (3)


multipart/form-data закодированные запросы действительно по умолчанию не поддерживаются API сервлетов до версии 3.0. API сервлетов по умолчанию анализирует параметры с использованием кодировки application/x-www-form-urlencoded. При использовании другой кодировки все вызовы request.getParameter() вернут null. Когда вы уже используете Servlet 3.0 (Glassfish 3, Tomcat 7 и т. д.), тогда вы можете использовать _ 5_. Дополнительные примеры см. В этом блоге.

До Servlet 3.0 стандарт de facto для синтаксического анализа multipart/form-data запросов использовал Apache Commons FileUpload. Просто внимательно прочтите разделы Руководство пользователя и Часто задаваемые вопросы, чтобы узнать, как им пользоваться. Я опубликовал ответ с примером кода перед здесь (это также содержит пример, ориентированный на сервлет 3.0).

person BalusC    schedule 26.07.2010
comment
Будь осторожен. Некоторая документация на сайте apache неверна. Например, они говорят, что вы можете вызвать setRepository () для объекта FileItemFactory, что является ложным, потому что любой объект, реализующий FileItemFactory, имеет только один метод: createItem (). Так что не забудьте также прочитать javadocs. - person Cheruvim; 23.01.2014
comment
getParts() всегда возвращает ноль элементов. Почему в Java и Servlet 3.0 так сложно получать составные формы? Не могу поверить в это! - person basZero; 23.09.2016
comment
@basZero: ответ на повторяющийся вопрос уже объясняет, когда он будет пустым. - person BalusC; 23.09.2016
comment
@BalusC у вас есть ссылка? На этой странице довольно много информации - person basZero; 23.09.2016

Решения:

Решение А:

  1. Загрузите http://www.servlets.com/cos/index.html.
  2. Вызвать getParameters () на com.oreilly.servlet.MultipartRequest

Решение B:

  1. Загрузите http://jakarta.Apache.org/commons/fileupload/.
  2. Вызов readHeaders () в org.apache.commons.fileupload.MultipartStream

Решение C:

  1. Загрузите http://users.boone.net/wbrameld/multipartformdata/.
  2. Вызов getParameter на com.bigfoot.bugar.servlet.http.MultipartFormData

Решение D:

Используйте Struts. Struts 1.1 обрабатывает это автоматически.

Ссылка: http://www.jguru.com/faq/view.jsp?EID=1045507

person renura    schedule 20.03.2012
comment
Пожалуйста, опубликуйте несколько решений, так как эти ссылки могут исчезнуть в любое время в будущем. Это привлечет отрицательный рейтинг. - person Jafar Ali; 02.03.2014

Не всегда есть сервлет перед загрузкой (например, я мог бы использовать фильтр). Или может случиться так, что один и тот же контроллер (снова фильтр или сервелт) может выполнять множество действий, поэтому я думаю, что полагаюсь на эту конфигурацию сервлета для использования метода getPart (только для Servlet API> = 3.0), я не знаю , Мне не нравится.

В целом, я предпочитаю независимые решения, способные жить одному, и в этом случае http://commons.apache.org/proper/commons-fileupload/ является одним из них.

List<FileItem> multiparts = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
    for (FileItem item : multiparts) {
        if (!item.isFormField()) {
            //your operations on file
        } else {
            String name = item.getFieldName();
            String value = item.getString();
            //you operations on paramters
        }
}
person Luca Rasconi    schedule 09.06.2015
comment
он работает только тогда, когда у вас есть объект запроса. Но что в случае объекта потока или любых других данных объекта? - person Ak S; 23.11.2018
comment
Поток или любые другие данные объекта заменят запрос. Поэтому я бы проанализировал / прочитал поток или что-то еще, чтобы получить данные многостраничной формы. В любом случае у вас есть реальный пример? - person Luca Rasconi; 23.11.2018