Как загрузить файлы на сервер с помощью JSP/Servlet и Ajax?

Я создаю веб-приложение JSP/Servlet, и я хотел бы загрузить файл в сервлет через Ajax. Как мне это сделать? Я использую 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");
        }
    });
});

Однако он не отправляет содержимое файла.

Ответ 1

К моменту, начиная с текущей версии XMLHttpRequest версии 1, используемой jQuery, можно не загружать файлы с помощью JavaScript через XMLHttpRequest. Общим решением является создание JavaScript скрытого <iframe> и отправка формы ему вместо этого, чтобы создать впечатление, что оно происходит асинхронно. То же самое, что делает большинство плагинов для загрузки файлов jQuery, таких как плагин jQuery Form (пример здесь).

Предполагая, что ваш JSP с формой HTML переписан таким образом, чтобы он не был сломанным, когда клиент отключен JS (как сейчас...), как показано ниже:

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

Что касается стороны сервлета, здесь особых действий не требуется. Просто реализуйте его точно так же, как если бы вы не использовали Ajax: Как загрузить файлы на сервер с помощью JSP/Servlet?

Вам потребуется дополнительная проверка сервлета, если заголовок X-Requested-With равен XMLHttpRequest или нет, так что вы знаете, каким образом ответ возвращается для случая, когда клиент отключен JS (как теперь это, в основном, более старые мобильные браузеры, которые отключили JS).

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

Обратите внимание, что относительно новая версия XMLHttpRequest версия 2 может отправлять выбранный файл с использованием новых API File и FormData. См. Также Загрузка файла HTML5 на Java Servlet и отправка файла как multipart через xmlHttpRequest.

Ответ 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>

Ответ 3

Код @Monsif хорошо работает, если форма имеет только входные данные типа файла, если есть другие другие файлы, кроме типа файла, то они теряются. Таким образом, вместо копирования данных каждой формы и добавления их к объекту FormData исходная форма может быть предоставлена ​​конструктору.

Что касается кода @Monsif и https://www.new-bamboo.co.uk/blog/2012/01/10/ridiculously-simple-ajax-uploads-with-formdata/, я вышел со следующим кодом, который работал у меня. Надеюсь, это поможет кому-то другому.

<script type="text/javascript">
        var files = null; // when files input changes this will be initiliazed.
        $(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>

Ответ 4

Этот код работает для меня.

Используется commons io.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>