1、springmvc支持文件上传,需要在spring-mvc.xml配置文件中加上下面的一段话:
<!-- 支持上传文件 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
2、下面介绍下XMLHttpRequest2.0
最早,微软在IE 5引进了这个接口。因为它太有用,其他浏览器也模仿部署了,ajax操作因此得以诞生。
但是,这个接口一直没有标准化,每家浏览器的实现或多或少有点不同。HTML 5的概念形成后,W3C开始考虑标准化这个接口。2008年2月,就提出了XMLHttpRequest Level 2 草案。
这个XMLHttpRequest的新版本,提出了很多有用的新功能,将大大推动互联网革新。本文就对这个新版本进行详细介绍。
老版本的XMLHttpRequest对象有以下几个缺点:
* 只支持文本数据的传送,无法用来读取和上传二进制文件。
* 传送和接收数据时,没有进度信息,只能提示有没有完成。
* 受到"同域限制"(Same Origin Policy),只能向同一域名的服务器请求数据
新版本的XMLHttpRequest对象,针对老版本的缺点,做出了大幅改进:
* 可以设置HTTP请求的时限。
* 可以使用FormData对象管理表单数据。
* 可以上传文件。
* 可以请求不同域名下的数据(跨域请求)。
* 可以获取服务器端的二进制数据。
* 可以获得数据传输的进度信息。
新版XMLHttpRequest对象,不仅可以发送文本信息,还可以上传文件。假定files是一个"选择文件"的表单元素(input[type="file"]),我们将它装入FormData对象。
var formData = new FormData(); for (var i = 0; i < files.length;i++) { formData.append('files[]', files[i]); }
然后,发送这个FormData对象
xhr.send(formData);
3、代码实现
废话不多说,上代码:
前端页面代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>XMLHttpRequest上传文件进度实现</title> <script type="text/javascript"> var xhr; var ot; // var oloaded; //上传文件方法 function UpladFile() { var fileObj = document.getElementById("uploadForm"); // js 获取文件对象 var url = "http://192.168.0.116:8080/partnersys/service/uploadFile"; // 接收上传文件的后台地址 var form = new FormData(fileObj); // FormData 对象 xhr = new XMLHttpRequest(); // XMLHttpRequest 对象 xhr.open("post", url, true); //post方式,url为服务器请求地址,true 该参数规定请求是否异步处理。 xhr.onload = uploadComplete; //请求完成 xhr.onerror = uploadFailed; //请求失败 xhr.upload.onprogress = progressFunction; //【上传进度调用方法实现】 xhr.upload.onloadstart = function() { //上传开始执行方法 ot = new Date().getTime(); //设置上传开始时间 oloaded = 0; //设置上传开始时,以上传的文件大小为0 }; xhr.send(form); //开始上传,发送form数据 } //上传进度实现方法,上传过程中会频繁调用该方法 function progressFunction(evt) { var progressBar = document.getElementById("progressBar"); var percentageDiv = document.getElementById("percentage"); // event.total是需要传输的总字节,event.loaded是已经传输的字节。如果event.lengthComputable不为真,则event.total等于0 if (evt.lengthComputable) { // progressBar.max = evt.total; progressBar.value = evt.loaded; percentageDiv.innerHTML = Math.round(evt.loaded / evt.total * 100) + "%"; } var time = document.getElementById("time"); var nt = new Date().getTime(); //获取当前时间 var pertime = (nt - ot) / 1000; //计算出上次调用该方法时到现在的时间差,单位为s ot = new Date().getTime(); //重新赋值时间,用于下次计算 var perload = evt.loaded - oloaded; //计算该分段上传的文件大小,单位b oloaded = evt.loaded; //重新赋值已上传文件大小,用以下次计算 //上传速度计算 var speed = perload / pertime; //单位b/s var bspeed = speed; var units = 'b/s'; //单位名称 if (speed / 1024 > 1) { speed = speed / 1024; units = 'k/s'; } if (speed / 1024 > 1) { speed = speed / 1024; units = 'M/s'; } speed = speed.toFixed(1); //剩余时间 var resttime = ((evt.total - evt.loaded) / bspeed).toFixed(1); time.innerHTML = ',速度:' + speed + units + ',剩余时间:' + resttime + 's'; if (bspeed == 0) time.innerHTML = '上传已取消'; } //上传成功响应 function uploadComplete(evt) { //服务断接收完文件返回的结果 // alert(evt.target.responseText); alert("上传成功!"); } //上传失败 function uploadFailed(evt) { alert("上传失败!"); } //取消上传 function cancleUploadFile() { xhr.abort(); } </script> </head> <body> <progress id="progressBar" value="0" max="100" style=" 300px;"></progress> <span id="percentage"></span><span id="time"></span> <br /> <br /> <form id="uploadForm" method="post" enctype="multipart/form-data"> <input type="file" id="file" name="myfile" /><!-- input标签的name属性用于post传输,作为表单的键值,后台通过键值获取序列化后的表单数据。name属性值和springmvc中的“@RequestParam(value = "myfile", required = true)”的value值相同,通过该值反序列化成springmvc的MultipartFile对象 --> <input type="button" onclick="UpladFile()" value="上传" /> <input type="button" onclick="cancleUploadFile()" value="取消" /> </form> </body> </html>
后端java代码:
@RequestMapping(value = "/uploadFile",method = RequestMethod.POST) public void upload(@RequestParam(value = "myfile", required = true) MultipartFile file, HttpServletRequest request, HttpServletResponse response) { String path = request.getSession().getServletContext().getRealPath("uploadFile"); String fileName = file.getOriginalFilename(); System.out.println("文件上传路径为:" + path); File targetFile = new File(path, fileName); if (!targetFile.exists()) { targetFile.mkdirs(); } // 保存 try { file.transferTo(targetFile); } catch (Exception e) { e.printStackTrace(); } }