Как загрузить файлы на сервер, используя JSP/Servlet и Ajax?
Я создаю веб-приложение JSP/Servlet и хочу загрузить файл в 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");
}
});
});
Тем не менее, это не похоже на отправку содержимого файла.
4 ответа
К моменту, по состоянию на текущий 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 способна отправить выбранный файл, используя новый File
а также FormData
API-интерфейсы. См. Также Загрузка файла HTML5 в сервлет Java и отправка файла как составного элемента через xmlHttpRequest.
Код @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>
Этот код прекрасно работает для меня:
$('#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>
Этот код работает для меня.
Используется 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>
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();
}
}
}
enter code here