【问题标题】:How can I upload files to a server using JSP/Servlet and Ajax?如何使用 JSP/Servlet 和 Ajax 将文件上传到服务器?
【发布时间】:2016-07-15 01:39:32
【问题描述】:

我正在创建一个 JSP/Servlet Web 应用程序,我想通过 Ajax 将一个文件上传到一个 servlet。我该怎么做呢?我正在使用 jQuery。

到目前为止我已经完成了:

<form class="upload-box">
    <input type="file" id="file" name="file1" />
    <span id="upload-error" class="error" />
    <input type="submit" id="upload-button" value="upload" />
</form>

使用这个 jQuery:

$(document).on("#upload-button", "click", function() {
    $.ajax({
        type: "POST",
        url: "/Upload",
        async: true,
        data: $(".upload-box").serialize(),
        contentType: "multipart/form-data",
        processData: false,
        success: function(msg) {
            alert("File has been uploaded successfully");
        },
        error:function(msg) {
            $("#upload-error").html("Couldn't upload file");
        }
    });
});

但是,它似乎没有发送文件内容。

【问题讨论】:

标签: jquery ajax jsp servlets file-upload


【解决方案1】:

$('#fileUploader').on('change', uploadFile);


function uploadFile(event)
    {
        event.stopPropagation(); 
        event.preventDefault(); 
        var files = event.target.files; 
        var data = new FormData();
        $.each(files, function(key, value)
        {
            data.append(key, value);
        });
        postFilesData(data); 
     }
    
function postFilesData(data)
    {
     $.ajax({
        url: 'yourUrl',
        type: 'POST',
        data: data,
        cache: false,
        dataType: 'json',
        processData: false, 
        contentType: false, 
        success: function(data, textStatus, jqXHR)
        {
            //success
        },
        error: function(jqXHR, textStatus, errorThrown)
        {
            console.log('ERRORS: ' + textStatus);
        }
        });
    }
<form method="POST" enctype="multipart/form-data">
    <input type="file" name="file" id="fileUploader"/>
</form>

【讨论】:

    【解决方案2】:

    Monsif's code 如果表单只有文件类型输入,则效果很好。如果除了文件类型之外还有其他一些输入,那么它们就会丢失。因此,无需复制每个表单数据并将它们附加到 FormData 对象,而是可以将原始表单本身提供给构造函数。

    <script type="text/javascript">
            var files = null; // when files input changes this will be initialised.
            $(function() {
                $('#form2Submit').on('submit', uploadFile);
        });
    
            function uploadFile(event) {
                event.stopPropagation();
                event.preventDefault();
                //var files = files;
                var form = document.getElementById('form2Submit');
                var data = new FormData(form);
                postFilesData(data);
    }
    
            function postFilesData(data) {
                $.ajax({
                    url :  'yourUrl',
                    type : 'POST',
                    data : data,
                    cache : false,
                    dataType : 'json',
                    processData : false,
                    contentType : false,
                    success : function(data, textStatus, jqXHR) {
                        alert(data);
                    },
                    error : function(jqXHR, textStatus, errorThrown) {
                        alert('ERRORS: ' + textStatus);
                    }
                });
            }
    </script>
    

    HTML 代码可以如下所示:

    <form id ="form2Submit" action="yourUrl">
      First name:<br>
      <input type="text" name="firstname" value="Mickey">
      <br>
      Last name:<br>
      <input type="text" name="lastname" value="Mouse">
      <br>
    <input id="fileSelect" name="fileSelect[]" type="file" multiple accept=".xml,txt">
    <br>
      <input type="submit" value="Submit">
    </form>
    

    【讨论】:

    • 链接已损坏:“页面未找到”
    • 正在删除死链接。
    【解决方案3】:

    此代码对我有用。

    我使用了Commons IOio.jar、Commons 文件upload.jar 和jQuery 表单插件:

    <script>
        $(function() {
            $('#upload-form').ajaxForm({
                success: function(msg) {
                    alert("File has been uploaded successfully");
                },
                error: function(msg) {
                    $("#upload-error").text("Couldn't upload file");
                }
            });
        });
    </script>
    <form id="upload-form" class="upload-box" action="upload" method="POST" enctype="multipart/form-data">
        <input type="file" id="file" name="file1" />
        <span id="upload-error" class="error">${uploadError}</span>
        <input type="submit" id="upload-button" value="upload" />
    </form>
     boolean isMultipart = ServletFileUpload.isMultipartContent(request);
    
     if (isMultipart) {
         // Create a factory for disk-based file items
         FileItemFactory factory = new DiskFileItemFactory();
    
         // Create a new file upload handler
         ServletFileUpload upload = new ServletFileUpload(factory);
    
         try {
             // Parse the request
             List items = upload.parseRequest(request);
             Iterator iterator = items.iterator();
             while (iterator.hasNext()) {
                 FileItem item = (FileItem) iterator.next();
                 if (!item.isFormField()) {
                     String fileName = item.getName();
                     String root = getServletContext().getRealPath("/");
                     File path = new File(root + "../../web/Images/uploads");
                     if (!path.exists()) {
                         boolean status = path.mkdirs();
                     }
    
                     File uploadedFile = new File(path + "/" + fileName);
                     System.out.println(uploadedFile.getAbsolutePath());
                     item.write(uploadedFile);
                 }
             }
         } catch (FileUploadException e) {
             e.printStackTrace();
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
    

    【讨论】:

    • 感谢您提供服务器端 Java 代码示例以阅读所发布的内容。大多数帖子只显示 Javascript,但在 Java 中的处理与大多数不同。
    【解决方案4】:

    到目前为止,从 jQuery 使用的当前 XMLHttpRequest 版本 1 开始,可以通过 XMLHttpRequest 使用 JavaScript 上传文件。常见的解决方法是让 JavaScript 创建一个隐藏的&lt;iframe&gt;,然后将表单提交给它,以便给人一种异步发生的印象。这也是大多数 jQuery 文件上传插件正在做的事情,例如 jQuery Form plugin (an example)。

    假设您的带有 HTML 表单的 JSP 以这样的方式重写,以便在客户端禁用 JavaScript 时它不会损坏(就像您现在...),如下所示:

    <form id="upload-form" class="upload-box" action="/Upload" method="post" enctype="multipart/form-data">
        <input type="file" id="file" name="file1" />
        <span id="upload-error" class="error">${uploadError}</span>
        <input type="submit" id="upload-button" value="upload" />
    </form>
    

    然后,借助 jQuery Form 插件,只需

    <script src="jquery.js"></script>
    <script src="jquery.form.js"></script>
    <script>
        $(function() {
            $('#upload-form').ajaxForm({
                success: function(msg) {
                    alert("File has been uploaded successfully");
                },
                error: function(msg) {
                    $("#upload-error").text("Couldn't upload file");
                }
            });
        });
    </script>
    

    至于 servlet 方面,这里不需要做任何特殊的事情。只需以与不使用 Ajax 时完全相同的方式实现它:How can I upload files to a server using JSP/Servlet?

    如果X-Requested-With 标头是否等于XMLHttpRequest,您只需要在 servlet 中进行额外检查,以便您知道在客户端禁用 JavaScript 的情况下返回什么样的响应(截至现在,主要是旧的移动浏览器禁用了 JavaScript)。

    if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
        // Return an Ajax response (e.g. write JSON or XML).
    } else {
        // Return a regular response (e.g. forward to JSP).
    }
    

    请注意,相对较新的 XMLHttpRequest 版本 2 能够使用新的 FileFormData API 发送选定的文件。另请参阅 HTML5 drag and drop file upload to Java ServletSend a file as multipart through XMLHttpRequest

    【讨论】:

    • @BalusC 关于 XMLHttpRequest 版本 1 的任何想法?我的意思是new FormData() 不工作的地方.. 见developer.mozilla.org/en-US/docs/Web/API/…
    • @BalusC 我明白你的意思了 :).. 啊,让我说到重点.. 我在 IE 8 和 9 上使用相同的插件,但没有响应,它说 NO Transport.. 有什么想法吗?
    • @Derek:marc_s 没有发布任何内容。如果您指的是 Sameera Madushanka 的答案,请注意他发布了侏罗纪方法。自 2009 年(十年前!)以来,他的方法就不再需要了。我的答案中标题为“如何使用 JSP/Servlet 将文件上传到服务器?”的链接。显示了使用HttpServletRequest#getParts() 的最新方法。下次,请阅读答案中的文本和代码 sn-ps 周围的链接,以免错过重要信息。
    猜你喜欢
    • 2016-06-18
    相关资源
    最近更新 更多