ServletFileUpload#parseRequest(request) возвращает пустой список

у меня есть клиентское приложение в Android, который использует HttpURLConnection для отправки файлов на сервер. Сервер использует API Apache Commons FileUpload для анализа значений данных формы.

на HttpURLConnection отправляет этот запрос:

-----------------------------4912995119421
Content-Disposition: form-data; name="deviceid"

9428103
-----------------------------4912995119421
Content-Disposition: form-data; name="countryid"

598
-----------------------------4912995119421
Content-Disposition: form-data; name="number"

98621360
-----------------------------4912995119421
Content-Disposition: form-data; name="file"; filename="2012-12-08 17.42.18.jpg"
Content-Type: image/jpeg

ÿØÿá1 Exif  II*    
      @      °      ª    
   ²              ¼       Ä   (       1    Ì   2    Ø          i‡    ì   %ˆ      n  SAMSUNG GT-S5360L H      H      S5360LUHLB1 2012:12:08 17:42:18  š‚    î  ?‚    ö  "ˆ       'ˆ    È    ?    0220?    þ  ?      ‘     ’    &  ’       
’    .        0100             @       °       >  £       ¤        ¤        ¤    6  ¤                     
   2012:12:08 17:42:18 2012:12:08 17:42:18    
     d               R98      0100                         (           ¤      T.      ÿØÿà JFIF      ÿÛ C @@ÿÛ 
-----------------------------4912995119421--

сервер код:

    String contentType = request.getContentType();
    if ((contentType.indexOf("multipart/form-data") == -1)) {
        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        return;
    }


    long maxFileSize = (2 * 1024 * 1024);

    int maxMemSize = (2 * 1024 * 1024);

    DiskFileItemFactory factory = new DiskFileItemFactory();
    // maximum size that will be stored in memory
    factory.setSizeThreshold(maxMemSize);

    // Create a new file upload handler
    ServletFileUpload upload = new ServletFileUpload(factory);
    // maximum file size to be uploaded.

    upload.setSizeMax(maxFileSize);

    List fileItems = upload.parseRequest(request);
    Iterator i = fileItems.iterator();


    //leo primero todas las variables.

    int deviceID = 0;
    int countryID = 0;
    String phoneNumber = "";



    while (i.hasNext()) {
        FileItem fi = (FileItem) i.next();

        if (fi.isFormField()) {
            String variable = fi.getFieldName();
            if (variable.equals("deviceid")) {
                deviceID = Integer.parseInt(fi.getString());
            } else if (variable.equals("countryid")) {
                countryID = Integer.parseInt(fi.getString());
            } else if (variable.equals("number")) {
                phoneNumber = String.valueOf(Long.parseLong(fi.getString()));
            }

        }

    }

    if (deviceID == 0 || countryID == 0 || phoneNumber.equals("")) {
        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

проблема в строке List fileItems = upload.parseRequest(request);. Возвращаемый список пуст, и я не могу получить значения form-data.

5 ответов


он будет пуст в этот момент, если вы уже (неявно) проанализировали тело запроса заранее. Тело HTTP-запроса может быть прочитано / проанализировано только один раз (как клиент отправил его только один раз и не отправить его несколько раз).

тело запроса будет неявно прочитано / проанализировано при вызове любого из следующих методов до подача запроса в Commons FileUpload:

request.getParameter();
request.getParameterMap();
request.getParameterNames();
request.getParameterValues();
request.getReader();
request.getInputStream();

вы должны быть абсолютно уверены, что ты не вызов любого из этих методов заранее (также проверьте все сервлет фильтр, чтобы быть уверенным).

Если вы уже гарантировали, что вы этого не делаете, то единственными другими возможными причинами будет неправильный заголовок границы и/или использование неправильных новых строк (это действительно должен быть CR+LF и, следовательно, не только LF). Вы можете найти конкретный и правильный пример в нижней части использование java.сеть.URLConnection для запуска и обработки HTTP-запросов, под раздел "Загрузка файлов".


У меня была такая же проблема после попытки я обнаружил, что это несовместимость библиотек, библиотека Apache server с библиотекой fileupload, поэтому я удаляю библиотеку и импортирую с библиотечного сервера Apache.

imports:
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;

к сожалению, мой английский


Если используется весна, проверьте, есть ли <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" /> в xml-файле. Существует функция

protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
        if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
            if (request instanceof MultipartHttpServletRequest) {
                logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " +
                        "this typically results from an additional MultipartFilter in web.xml");
            }
            else {
                return this.multipartResolver.resolveMultipart(request);
            }
        }
        // If not returned before: return original request.
        return request;
    }

" ест " составные элементы. Это вызывает трехчасовую боль.


Я также столкнулся с этой проблемой, но я не мог найти ничего, что конкретно связано с чтением объекта запроса. Я, наконец, заставил его работать, удалив этот блок:

@MultipartConfig(
    location="/tmp", 
    fileSizeThreshold=1024*1024, 
    maxFileSize=1024*1024*5, 
    maxRequestSize=1024*1024*5*5
)

по-видимому, когда я пытался прочитать запрос с помощью getParts (), я забыл удалить это. Я немного новичок в java, поэтому я не знал, что это конфликтует с ServletFileUpload#parseRequest. Во всяком случае, как только я избавился от него, parseRequest правильно вернул массив.


моя проблема-контекст apache.xml на моем сервере linux содержит контекст

allowCasualMultipartParsing="true" и мой HttpServlet содержит

@MultipartConfig(fileSizeThreshold=1024*1024*2,maxFileSize=1024*1024*50,maxRequestSize=1024*1024*50)

Я удаляю его, тогда он работает правильно. Надеюсь, это поможет вам.