【问题标题】:ServletFileUpload#parseRequest(request) returns an empty listServletFileUpload#parseRequest(request) 返回一个空列表
【发布时间】:2012-12-02 14:34:55
【问题描述】:

我在 Android 中有一个客户端应用程序,它使用 HttpURLConnection 将文件发送到服务器。服务器使用 Apache Commons FileUpload API 来解析表单数据值。

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); 行。 返回的列表为空,我无法获取表单数据值。

【问题讨论】:

    标签: java http servlets file-upload multipartform-data


    【解决方案1】:

    我的问题是我的 linux 服务器上的 apache context.xml 包含上下文

    allowCasualMultipartParsing="true" 和我的 HttpServlet 包含

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

    我删除它然后它就可以正常工作了。希望这会帮助你。

    【讨论】:

      【解决方案2】:

      如果使用spring,检查xml文件中是否有<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />。有一个功能

      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;
          }
      

      “吃掉”多部分项目。它会导致三个小时的疼痛。

      【讨论】:

        【解决方案3】:

        我在尝试后遇到了同样的问题,我发现这是库不兼容,库 apache 服务器与 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;
        

        对不起我的英语

        【讨论】:

        • 这个解决方案不起作用,因为来自 tomcat 的 ServletFileUpload.parseRequest 需要一个 RequestContext 类型的参数,一个来自同一个 tomcat 库的类,而来自 commons 的 ServletFileUpload.parseRequest 需要来自 servlet 的 HttpServletRequest 类型的参数API。因此,如果您更改导入,代码将无法编译。
        【解决方案4】:

        我也遇到了这个问题,但是我找不到与读取请求对象特别相关的任何内容。我终于通过删除这个块让它工作了:

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

        显然,当我尝试使用 getParts() 读取请求时,我忘了删除它。我对 java 有点陌生,所以我不知道这与 ServletFileUpload#parseRequest 冲突。无论如何,一旦我摆脱它, parseRequest 正确地返回了数组。

        【讨论】:

          【解决方案5】:

          如果您已经(隐式)事先解析了请求正文,那么此时它将为空。 HTTP 请求正文只能被读取/解析一次(因为客户端只发送了一次,不会发送多次)。

          当您调用以下任何方法将请求提供给 Commons FileUpload 之前,请求正文将被隐式读取/解析:

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

          您需要绝对确保您事先没有调用任何这些方法(还要检查所有 servlet 过滤器以确保)。

          如果你已经确定你没有这样做,那么唯一可能的原因是边界标题不正确和/或使用了不正确的换行符(它必须是 CR+LF,因此不仅仅是 LF) .您可以在Using java.net.URLConnection to fire and handle HTTP requests 底部的“上传文件”部分下找到一个具体且适当的示例。

          【讨论】:

          • 我检查过:request.getInputStream() byte[] a = new byte[8096];诠释 r = 0; ServletInputStream s = request.getInputStream();字符串 c = ""; while ((r = s.read(a)) != -1) { c += new String(a).substring(0, r);并收到数据ok。问题是普通文件上传无法解析内容。
          • 好吧,如果您删除了 request.getInputStream() 电话,那么它应该可以正常工作,正如我在回答中所解释的那样。
          • 好的,我假设您没有事先调用任何提到的方法。这个问题只能意味着你没有设置正确的边界标题,或者你使用了错误的换行符。您可以在stackoverflow.com/a/2793153 底部的“上传文件”部分下找到一个具体且适当的示例。
          • 我设置的时候有个小错误:connection.setRequestProperty("content-type", "multipart / form-data, boundary="+boundary0);错误地在边界前添加“-”。
          • 我在空列表中遇到了类似的问题,但问题实际上出在这个参数 Locale lang public void uploadFile(Locale lang, ModelMap model, HttpServletRequest request, HttpServletResponse response) 我只是删除了这个参数,我花了一整天的时间才弄清楚
          猜你喜欢
          • 2014-07-20
          • 2021-07-22
          • 1970-01-01
          • 1970-01-01
          • 2012-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-23
          相关资源
          最近更新 更多