如何使用 JSP/Servlet 和 Ajax 将文件上传到服务器?

How can I upload files to a server using JSP/Servlet and Ajax?

提问人:Nachshon Schwartz 提问时间:8/2/2011 最后编辑:Peter MortensenNachshon Schwartz 更新时间:10/28/2021 访问量:77781

问:

我正在创建一个 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 servlet 文件上传

评论

0赞 Paolo Biavati 9/22/2012
可以使用 XMLHttpRequest 方法。看看这个:stackoverflow.com/questions/6974684/......
0赞 gred 8/2/2011
希望这对您有所帮助:http://www.webdeveloperjuice.com/2010/02/13/7-trusted-ajax-file-upload-plugins-using-jquery/

答:

23赞 BalusC 8/3/2011 #1

说到jQuery使用的当前版本1起,无法通过JavaScript上传文件。常见的解决方法是让 JavaScript 创建一个隐藏的表单并将表单提交给它,以便产生异步发生的印象。这也正是大多数jQuery文件上传插件正在做的事情,例如jQuery表单插件一个示例)。XMLHttpRequestXMLHttpRequest<iframe>

假设你的 JSP 和 HTML 表单是这样重写的,这样当客户端禁用了 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 时一样实现它:如何使用 JSP/Servlet 将文件上传到服务器?

如果标头是否相等,您只需要在 servlet 中进行额外的检查,以便您知道在客户端禁用了 JavaScript 的情况下如何返回哪种响应(截至目前,主要是禁用了 JavaScript 的旧移动浏览器)。X-Requested-WithXMLHttpRequest

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).
}

请注意,相对较新的版本 2 能够使用新的 API 和 API 发送选定的文件。另请参阅 HTML5 将文件拖放上传到 Java Servlet通过 XMLHttpRequest 将文件作为分段发送。XMLHttpRequestFileFormData

评论

0赞 Aman Gupta 1/7/2014
@BalusC XMLHttpRequest 版本 1 有任何想法吗?我的意思是哪里不工作..请参阅 developer.mozilla.org/en-US/docs/Web/API/...new FormData()
0赞 Aman Gupta 1/7/2014
@BalusC我明白你的意思:)。啊,让我直奔主题..我在 IE 8 和 9 中使用相同的插件,但没有响应,它说没有传输。任何想法 ?
0赞 BalusC 10/31/2019
@Derek:marc_s没有发布任何内容。如果您指的是 Sameera Madushanka 的答案,那么请注意他发布了侏罗纪的方法。自 2009 年以来(十年前!我的回答中标题为“如何使用JSP/Servlet将文件上传到服务器?”的链接显示了使用的最新方法。下次,请在错过重要信息之前阅读答案中代码片段周围的文本和链接。HttpServletRequest#getParts()
2赞 Monsif EL AISSOUSSI 11/24/2015 #2

$('#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>

5赞 Memin 10/12/2016 #3

如果表单只有文件类型输入,则 Monsif 的代码效果很好。如果除了文件类型之外还有其他一些输入,那么它们就会丢失。因此,可以将原始表单本身提供给构造函数,而不是复制每个表单数据并将它们附加到 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>

评论

1赞 Peter Mortensen 10/28/2021
链接已损坏:“找不到页面”
0赞 Memin 10/28/2021
正在删除死链接。
0赞 Sameera Madushanka 12/23/2016 #4

这段代码对我有用。

我使用了Commons IO的io.jar,共享资源文件上传.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();
     }
 }

评论

0赞 Derek Wade 10/29/2019
感谢您提供服务器端 Java 代码示例来阅读发布的内容。大多数帖子只显示 Javascript,但 Java 中的处理方式与大多数帖子不同。