【问题标题】:HTML5 drag and drop file upload to Java ServletHTML5 拖放文件上传到 Java Servlet
【发布时间】:2011-10-30 03:44:12
【问题描述】:

我目前正在成功地使用 Uploadify (Flash + Ajax) 到 Servlet(使用 OWASP ESAPI 覆盖的公共上传),但我想知道如何构建 HTML5 支持,或者更确切地说是支持 Flash 的 HTML5。

我知道如何让 HTML5 拖放工作,但我不能完全弄清楚 Java Servlet 连接和/或后端的机制。

【问题讨论】:

    标签: html servlets file-upload drag-and-drop


    【解决方案1】:

    您需要多部分配置,例如:

    @MultipartConfig(fileSizeThreshold = 1024 * 1024, 
                     maxFileSize = 1024 * 1024 * 5, 
                     maxRequestSize = 1024 * 1024 * 5 * 5)
    

    在我的情况下,它只适用于这种配置。

    【讨论】:

      【解决方案2】:

      我知道如何让 HTML5 DnD 工作,但我不能完全弄清楚 Java Servlet 连接和/或后端的机制。

      这与使用常规 <form enctype="multipart/form-data"> 时没有什么不同。您需要做的就是让 HTML5/JS 代码发送带有已删除文件的 multipart/form-data 请求,该请求与使用常规 <input type="file"> 字段发送的请求完全相同。我假设您只是不知道如何使用 HTML5/JS 来实现这一点。

      您可以为此使用新的 HTML5 File API、XHR2 FormDataXMLHttpRequestUpload API。

      这是一个启动示例,说明您的 drop 事件处理程序应该是什么样子:

      function dropUpload(event) {
          event.stopPropagation();
          event.preventDefault();
      
          var formData = new FormData();
          formData.append("file", event.dataTransfer.files[0]);
      
          var xhr = new XMLHttpRequest();
          xhr.open("POST", "uploadServlet");
          xhr.send(formData);
      }
      

      就是这样。此示例假定 servlet 映射到 /uploadServlet 的 URL 模式。在此示例中,该文件随后可以在 Apache Commons FileUpload 中以通常的方式作为 FileItem 实例使用,字段名称为 file


      有关更高级的内容,例如附加事件处理程序以监控进度等,请查看以下博客:

      我已经使用以下 SSCCE 进行了一些尝试:

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <title>HTML5 drag'n'drop file upload with Servlet</title>
              <script>
                  window.onload = function() {
                      var dropbox = document.getElementById("dropbox");
                      dropbox.addEventListener("dragenter", noop, false);
                      dropbox.addEventListener("dragexit", noop, false);
                      dropbox.addEventListener("dragover", noop, false);
                      dropbox.addEventListener("drop", dropUpload, false);
                  }
      
                  function noop(event) {
                      event.stopPropagation();
                      event.preventDefault();
                  }
      
                  function dropUpload(event) {
                      noop(event);
                      var files = event.dataTransfer.files;
      
                      for (var i = 0; i < files.length; i++) {
                          upload(files[i]);
                      }
                  }
      
                  function upload(file) {
                      document.getElementById("status").innerHTML = "Uploading " + file.name;
      
                      var formData = new FormData();
                      formData.append("file", file);
      
                      var xhr = new XMLHttpRequest();
                      xhr.upload.addEventListener("progress", uploadProgress, false);
                      xhr.addEventListener("load", uploadComplete, false);
                      xhr.open("POST", "uploadServlet", true); // If async=false, then you'll miss progress bar support.
                      xhr.send(formData);
                  }
      
                  function uploadProgress(event) {
                      // Note: doesn't work with async=false.
                      var progress = Math.round(event.loaded / event.total * 100);
                      document.getElementById("status").innerHTML = "Progress " + progress + "%";
                  }
      
                  function uploadComplete(event) {
                      document.getElementById("status").innerHTML = event.target.responseText;
                  }
              </script>
              <style>
                  #dropbox {
                      width: 300px;
                      height: 200px;
                      border: 1px solid gray;
                      border-radius: 5px;
                      padding: 5px;
                      color: gray;
                  }
              </style>
          </head>
          <body>
              <div id="dropbox">Drag and drop a file here...</div>
              <div id="status"></div>
          </body>
      </html>
      

      而这个 UploadServlet 使用新的 Servlet 3.0 HttpServletRequest#getPart() API:

      @MultipartConfig
      @WebServlet("/uploadServlet")
      public class UploadServlet extends HttpServlet {
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              Part file = request.getPart("file");
              String filename = getFilename(file);
              InputStream filecontent = file.getInputStream();
              // ... Do your file saving job here.
      
              response.setContentType("text/plain");
              response.setCharacterEncoding("UTF-8");
              response.getWriter().write("File " + filename + " successfully uploaded");
          }
      
          private static String getFilename(Part part) {
              for (String cd : part.getHeader("content-disposition").split(";")) {
                  if (cd.trim().startsWith("filename")) {
                      String filename = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
                      return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1); // MSIE fix.
                  }
              }
              return null;
          }
      }
      

      另见:

      【讨论】:

      • 嘿BalusC,感谢您的回答,我们很乐意提供赏金,但是您知道是否可以使用新的 HTML5 File API 对文件进行排队,我可以关闭自动上传,但是似乎无法找到一种方法来对文件进行排队并从 jquery 动态启动上传...再次感谢。
      • SSCCE 只假设一个文件上传。用for 循环替换if 检查files。调用xhr.open(),将第三个参数(异步)设置为false。它将同步运行。您只会错过进度条支持。我已经编辑了这个例子。至于 jQuery,据我所知,它还没有 XHR2 支持。毕竟只是 JavaScript,我不明白为什么上面的例子应该在 jQuery 中完成。也许是元素选择器,但不是别的。可能已经有新的 XHR2 支持的 jQuery 插件。
      • hox 我可以在上传中添加自定义变量吗? (我需要这个来验证用户是否登录)
      • 这很好用。但是,我为每个上传的文件使用不同的进度条(多个“状态”)。有没有办法告诉“uploadProgress()”哪个 DOM 元素更新(哪个“状态”)?
      • 这有帮助:stackoverflow.com/questions/6728750/… 虽然我不喜欢内联函数
      猜你喜欢
      • 2011-09-24
      • 2011-09-08
      • 2011-12-23
      • 1970-01-01
      • 2011-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多