提问人:Nachshon Schwartz 提问时间:8/2/2011 最后编辑:Peter MortensenNachshon Schwartz 更新时间:10/28/2021 访问量:77781
如何使用 JSP/Servlet 和 Ajax 将文件上传到服务器?
How can I upload files to a server using JSP/Servlet and Ajax?
问:
我正在创建一个 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使用的当前版本1起,无法通过JavaScript上传文件。常见的解决方法是让 JavaScript 创建一个隐藏的表单并将表单提交给它,以便产生异步发生的印象。这也正是大多数jQuery文件上传插件正在做的事情,例如jQuery表单插件(一个示例)。XMLHttpRequest
XMLHttpRequest
<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-With
XMLHttpRequest
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 将文件作为分段发送。XMLHttpRequest
File
FormData
评论
new FormData()
HttpServletRequest#getParts()
$('#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>
如果表单只有文件类型输入,则 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>
评论
这段代码对我有用。
我使用了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();
}
}
评论