【问题标题】:HTML5 Directory Upload Java Servlet ProcessingHTML5 目录上传 Java Servlet 处理
【发布时间】:2014-05-14 13:00:33
【问题描述】:

我在玩HTML5webkitdirectory递归目录上传:

<form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file_input" webkitdirectory="" directory="">
    <input type="submit">
</form>

在服务器端,我使用 apache-commons-fileupload 1.3.1 (Streaming API) 处理它:

@WebServlet(urlPatterns = "/upload")
public class DirUploadServlet extends HttpServlet
{        
    @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        ServletFileUpload upload = new ServletFileUpload();

        response.setContentType(MediaType.TEXT_PLAIN);
        PrintWriter writer = response.getWriter();

        try
        {
            FileItemIterator iter = upload.getItemIterator(request);

            while (iter.hasNext())
            {
                FileItemStream item = iter.next();

                if (!item.isFormField())
                {
                    writer.println(item.getName());
                }
            }
        }
        catch (FileUploadException e)
        {
            throw new IOException(e);
        }
    }
}

这适用于没有子目录的目录。 但是,如果我尝试选择包含子目录的目录,请求会正确发送,但是在服务器端我得到以下异常:

org.apache.commons.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
    at org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:1005)
    at org.apache.commons.fileupload.MultipartStream$ItemInputStream.close(MultipartStream.java:943)
    at org.apache.commons.fileupload.MultipartStream$ItemInputStream.close(MultipartStream.java:922)
    at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl$FileItemStreamImpl.close(FileUploadBase.java:866)
    at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.findNextItem(FileUploadBase.java:1017)
    at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.hasNext(FileUploadBase.java:1106)
    at DirUploadServlet.doPost(DirUploadServlet.java:45)

这个请求(来自 Ubuntu Chromium)对我来说似乎是合法的:

------WebKitFormBoundaryMQ53uSzX0G6oZpWL
Content-Disposition: form-data; name="file_input"; filename="probadir/dir2/."
Content-Type: application/octet-stream


------WebKitFormBoundaryMQ53uSzX0G6oZpWL
Content-Disposition: form-data; name="file_input"; filename="probadir/file1"
Content-Type: application/octet-stream


------WebKitFormBoundaryMQ53uSzX0G6oZpWL
Content-Disposition: form-data; name="file_input"; filename="probadir/dir2/file2"
Content-Type: application/octet-stream


------WebKitFormBoundaryMQ53uSzX0G6oZpWL--

该错误与 Windows 中的 Google Chrome 相同。 IE 和 Firefox 还没有这个功能。

【问题讨论】:

    标签: java html servlets file-upload apache-commons-fileupload


    【解决方案1】:

    这里的问题不在于commons-fileupload,而在于请求或servlet 容器本身。当我使用 Glassfish 3.1.2 和 Servlet API 以二进制形式注销请求时,我收到以下代码:

    ------WebKitFormBoundary7AVw8qF0sdCpYB1P
    Content-Disposition: form-data; name="files[]"; filename="probadir/dir2/."
    Content-Type: application/octet-stream
    
    \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\
    \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\
    \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\
    \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\
    

    等等。和 0 字节直到结束。这就是为什么 commons-fileupload API 和 Servlet 3 中的 Multipart API(例如request.getPart())都会引发异常。

    现在我认为唯一的解决方案是不使用标准的 HTML 表单提交,而是使用此处解释的 JS 单独提交文件:Keep Directory Structure When Uploading

    【讨论】:

      猜你喜欢
      • 2011-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-06
      • 2013-11-17
      • 1970-01-01
      • 2016-06-05
      相关资源
      最近更新 更多