|
利用jQuery和HTML5的FormData异步上传文件的好处是:
- 实现很简单
- 很方便地支持进度条
- 很方便地进行扩展和美化
先看看效果图:

图片上传后的结果:

实现步骤如下:
第一步:配置好SpringMVC + servlet3.0 文件上传所需要的各种资源,参考:http://blog.csdn.net/clementad/article/details/49533189
第二步:上传页面的html代码:
-
<!DOCTYPE html>
-
<html>
-
<head>
-
<meta charset="UTF-8">
-
<link href="../resources/css/common.css" rel="stylesheet" />
-
<script src="../resources/js/jquery-2.1.4.js"></script>
-
-
</head>
-
-
<body>
-
<h2>HTML5异步上传文件,带进度条</h2>
-
<form method="post" enctype="multipart/form-data">
-
其他需要提交的信息:<input type="text" name="otherInfo"/><br/><br/>
-
选择要上传的文件:<br/>
-
<input type="file" name="file" /><span></span><br/>
-
<input type="file" name="file" /><span></span><br/>
-
</form>
-
-
<br/><br/>
-
<input type="button" value="上传吧" onclick="upload()"/>
-
<br/><br/>
-
上传进度:<progress></progress><br/>
-
<p id="progress">0
bytes</p>
-
<p id="info"></p>
-
</body>
-
</html>
-
<!DOCTYPE html>
-
<html>
-
<head>
-
<meta charset="UTF-8">
-
<link href="../resources/css/common.css" rel="stylesheet" />
-
<script src="../resources/js/jquery-2.1.4.js"></script>
-
-
</head>
-
-
<body>
-
<h2>HTML5异步上传文件,带进度条</h2>
-
<form method="post" enctype="multipart/form-data">
-
其他需要提交的信息:<input type="text" name="otherInfo"/><br/><br/>
-
选择要上传的文件:<br/>
-
<input type="file" name="file" /><span></span><br/>
-
<input type="file" name="file" /><span></span><br/>
-
</form>
-
-
<br/><br/>
-
<input type="button" value="上传吧" onclick="upload()"/>
-
<br/><br/>
-
上传进度:<progress></progress><br/>
-
<p id="progress">0 bytes</p>
-
<p id="info"></p>
-
</body>
-
</html>
第三步:异步上传的JavaScript代码(注释很详细):
-
<script>
-
var totalSize = 0;
-
-
-
$(':file').change(function()
{
-
var file = this.files[0];
-
name = file.name;
-
size = file.size;
-
type = file.type;
-
url = window.URL.createObjectURL(file);
-
-
$(this).next().html("文件名:" +
name + " 文件类型:" + type + " 文件大小:" +
size + " url: " + url);
-
-
totalSize += size;
-
-
$("#info").html("总大小: " + totalSize + "bytes");
-
-
});
-
-
function upload() {
-
-
var formData = new FormData($('form')[0]);
-
-
-
$.ajax({
-
url: "http://localhost:8080/MyJavaStudio/servlet/file/upload",
-
type: "POST",
-
data: formData,
-
xhr: function(){
-
-
myXhr = $.ajaxSettings.xhr();
-
if(myXhr.upload){
-
-
myXhr.upload.addEventListener('progress',progressHandlingFunction, false);
-
}
-
return myXhr;
-
},
-
success: function(result){
-
$("#result").html(result.data);
-
},
-
contentType: false,
-
processData: false
-
});
-
}
-
-
-
function progressHandlingFunction(e) {
-
if (e.lengthComputable) {
-
$('progress').attr({value : e.loaded, max : e.total});
-
var percent = e.loaded/e.total*100;
-
$('#progress').html(e.loaded + "/" +
e.total+" bytes. " + percent.toFixed(2) + "%");
-
}
-
}
-
</script>
-
<script>
-
var totalSize = 0;
-
-
-
$(':file').change(function() {
-
var file = this.files[0];
-
name = file.name;
-
size = file.size;
-
type = file.type;
-
url = window.URL.createObjectURL(file);
-
-
$(this).next().html("文件名:" + name + " 文件类型:" + type + " 文件大小:" + size + " url: " + url);
-
-
totalSize += size;
-
-
$("#info").html("总大小: " + totalSize + "bytes");
-
-
});
-
-
function upload() {
-
-
var formData = new FormData($('form')[0]);
-
-
-
$.ajax({
-
url: "http://localhost:8080/MyJavaStudio/servlet/file/upload",
-
type: "POST",
-
data: formData,
-
xhr: function(){
-
-
myXhr = $.ajaxSettings.xhr();
-
if(myXhr.upload){
-
-
myXhr.upload.addEventListener('progress',progressHandlingFunction, false);
-
}
-
return myXhr;
-
},
-
success: function(result){
-
$("#result").html(result.data);
-
},
-
contentType: false,
-
processData: false
-
});
-
}
-
-
-
function progressHandlingFunction(e) {
-
if (e.lengthComputable) {
-
$('progress').attr({value : e.loaded, max : e.total});
-
var percent = e.loaded/e.total*100;
-
$('#progress').html(e.loaded + "/" + e.total+" bytes. " + percent.toFixed(2) + "%");
-
}
-
}
-
</script>
第四步:SpringMVC写好接受和保持文件的Controller方法:
-
-
-
-
-
-
@RestController
-
@RequestMapping("/servlet/file")
-
public class FileUploadController
{
-
-
-
-
-
private static final String
SAVE_DIR = "uploadFiles";
-
-
-
-
-
-
-
-
-
-
-
@RequestMapping("/upload")
-
public JsonResult upload(HttpServletRequest request, HttpServletResponse response, @RequestParam Map<String,
Object> p)
-
throws ServletException, IOException {
-
-
-
String appPath = request.getServletContext().getRealPath("");
-
-
-
String savePath = appPath + File.separator + SAVE_DIR;
-
-
-
File fileSaveDir = new File(savePath);
-
if (!fileSaveDir.exists()) {
-
fileSaveDir.mkdirs();
-
}
-
-
List<String> fileNames = new ArrayList<>();
-
-
-
for (Part part : request.getParts()) {
-
String fileName = part.getSubmittedFileName();
-
-
-
-
if(!StringUtils.isEmpty(fileName)){
-
part.write(savePath + File.separator + fileName);
-
fileNames.add(fileName);
-
}
-
}
-
-
Map<String, Object> resultData = new HashMap<>();
-
resultData.put("savePath", savePath);
-
resultData.put("files", fileNames);
-
-
return new JsonResult("200", "文件上传成功!",
resultData);
-
}
-
-
-
-
-
-
-
-
-
-
-
@SuppressWarnings("unused")
-
private String extractFileName(Part part) {
-
String contentDisp = part.getHeader("content-disposition");
-
String[] items = contentDisp.split(";");
-
for (String s : items) {
-
if (s.trim().startsWith("filename"))
{
-
return s.substring(s.indexOf("=")
+ 2, s.length()-1);
-
}
-
}
-
return "";
-
}
-
-
}
-
-
-
-
-
-
@RestController
-
@RequestMapping("/servlet/file")
-
public class FileUploadController {
-
-
-
-
-
private static final String SAVE_DIR = "uploadFiles";
-
-
-
-
-
-
-
-
-
-
-
@RequestMapping("/upload")
-
public JsonResult upload(HttpServletRequest request, HttpServletResponse response, @RequestParam Map<String, Object> p)
-
throws ServletException, IOException {
-
-
-
String appPath = request.getServletContext().getRealPath("");
-
-
-
String savePath = appPath + File.separator + SAVE_DIR;
-
-
-
File fileSaveDir = new File(savePath);
-
if (!fileSaveDir.exists()) {
-
fileSaveDir.mkdirs();
-
}
-
-
List<String> fileNames = new ArrayList<>();
-
-
-
for (Part part : request.getParts()) {
-
String fileName = part.getSubmittedFileName();
-
-
-
-
if(!StringUtils.isEmpty(fileName)){
-
part.write(savePath + File.separator + fileName);
-
fileNames.add(fileName);
-
}
-
}
-
-
Map<String, Object> resultData = new HashMap<>();
-
resultData.put("savePath", savePath);
-
resultData.put("files", fileNames);
-
-
return new JsonResult("200", "文件上传成功!", resultData);
-
}
-
-
-
-
-
-
-
-
-
-
-
@SuppressWarnings("unused")
-
private String extractFileName(Part part) {
-
String contentDisp = part.getHeader("content-disposition");
-
String[] items = contentDisp.split(";");
-
for (String s : items) {
-
if (s.trim().startsWith("filename")) {
-
return s.substring(s.indexOf("=") + 2, s.length()-1);
-
}
-
}
-
return "";
-
}
-
-
}
最后那个私有方法可以不用的,只是为了演示如何直接获取request header中的数据。
最后,验证上传过程中的网络消息:
上传的消息头和数据:

可见,对于表单中的3个input,http request payload中对应有3个part来上传数据。
Controller处理后的返回结果(JSON格式):

总结:代码很简单,结果很友好,html5和SpringMVC!
|