前言
本文讨论基于Java SpringMVC框架的文件上传,将会详细说明基于Apache commons-fileupload的文件上传,其中,会介绍通过ajaxfileupload无刷新的ajax文件上传。
实现文件上传功能的具体步骤
1. 导入Apache commons-fileupload文件上传所需要的jar包
为了实现基于Apache commons-fileupload的文件上传,我们需要首先导入所需要的apache jar包,如下maven依赖项:
4. 配置web.xml
3. 在springmvc-servlet.xml配置文件中设置文件上传的相应配置细节
4. UploadController的实现
commens-fileupload上传文件方式
12345678910111213141516171819202122"/upload", method = RequestMethod.POST)(value =public String upload(MultipartFile file, HttpServletRequest request, Model model) throws IOException {if(file.isEmpty()) {System.out.println("文件不存在");return null;}// 获得原始文件名String fileName = file.getOriginalFilename();System.out.println("原始文件名:" + fileName);// 新文件名String name = UUID.randomUUID() + fileName;// 获得项目的路径ServletContext sc = request.getSession().getServletContext();// 上传位置String realPath = sc.getRealPath("/WEB-INF/upload");FileUtils.copyInputStreamToFile(file.getInputStream(), new File(realPath, name));System.out.println("文件上传成功");return null;}文件流上传方式
1234567891011121314151617181920212223"/upload", method = RequestMethod.POST)(value =public String upload(MultipartFile file, HttpServletRequest request, Model model) throws IOException {if(file.isEmpty()) {System.out.println("文件不存在");return null;}// 获得原始文件名String fileName = file.getOriginalFilename();System.out.println("原始文件名:" + fileName);// 新文件名String name = UUID.randomUUID() + fileName;// 获得项目的路径ServletContext sc = request.getSession().getServletContext();// 上传位置String realPath = sc.getRealPath("/WEB-INF/upload");File saveFile = new File(realPath, name);file.transferTo(saveFile);System.out.println("文件上传成功");return null;}一次上传多个文件
123456789101112131415161718192021222324"/add", method=RequestMethod.POST)(value=public String addUser(User user, @RequestParam MultipartFile[] myfiles, HttpServletRequest request) throws IOException{//如果只是上传一个文件,则只需要MultipartFile类型接收文件即可,而且无需显式指定@RequestParam注解//如果想上传多个文件,那么这里就要用MultipartFile[]类型来接收文件,并且还要指定@RequestParam注解//并且上传多个文件时,前台表单中的所有<input type="file"/>的name都应该是myfiles,否则参数里的myfiles无法获取到所有上传的文件for(MultipartFile myfile : myfiles){if(myfile.isEmpty()){System.out.println("文件未上传");} else {System.out.println("文件长度: " + myfile.getSize());System.out.println("文件类型: " + myfile.getContentType());System.out.println("文件名称: " + myfile.getName());System.out.println("文件原名: " + myfile.getOriginalFilename());System.out.println("========================================");//如果用的是Tomcat服务器,则文件会上传到\\%TOMCAT_HOME%\\webapps\\YourWebProject\\WEB-INF\\upload\\文件夹中String realPath = request.getSession().getServletContext().getRealPath("/WEB-INF/upload");//这里不必处理IO流关闭的问题,因为FileUtils.copyInputStreamToFile()方法内部会自动把用到的IO流关掉,我是看它的源码才知道的FileUtils.copyInputStreamToFile(myfile.getInputStream(), new File(realPath, myfile.getOriginalFilename()));}}return null;}
至此,上述内容为普通表单提交上传文件方式和ajax文件上传文件的公共部分。
一、表单提交commons-fileupload文件上传的实现方式
- 前端页面的实现:12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455<html><div id="page-content-wrapper"><div id="page-title"><h3>上传文件</h3></div><div id="page-content"><form id="form" action="/upload" method="POST" enctype="multipart/form-data"><div class="col-md-12"><div class="form-row"><div class="form-label col-md-2"><label for="">文件<span class="required">*</span></label></div><div class="form-input col-md-2"><input type="file" id="file" name="file" data-trigger="change" data-required="true"class="parsley-validated"value=""></div></div><div class="row pad5A"><div class="form-input col-md-1 col-md-offset-1"><a href="javascript:save();" class="btn large primary-bg radius-all-4" id="save"><span class="button-content">提交</span></a></div><div class="form-input col-md-1"><a href="/finance/financedata" class="btn large primary-bg radius-all-4" id="back"><span class="button-content">返回</span></a></div></div></div></form></div></div><script type="text/javascript" src="/assets/js/jquery-1.12.4.min.js"></script><script type="text/javascript" src="/assets/js/ajaxfileupload.js"></script><script>// 提交function save() {$('#form').parsley('validate');$('#form').submit();}</script></html>
当点击提交
按钮时,页面将会触发form表单的submit,页面将进行刷新并提交file文件,并访问UploadController中的/upload接口;
此处,form表单必须注明表单提交的是文件类型,即如下代码中的enctype="multipart/form-data"
设置,否则,页面将无法识别提交的内容,造成文件上传时失败;
二、ajax无刷新页面的文件上传方式
- 在实现ajax上传之前,我们的前端页面需要依赖ajaxfileupload.js文件进行依赖,ajaxfileupload的下载请自行搜索;需要说明的是,我们需要对ajaxfileupload.js文件进行修改,否则,在执行文件上传的过程中,将会出现如下2个错误:
a.jQuery.handleError is not a function;
解决方法(handlerError只在jquery-1.4.2之前的版本中存在,jquery-1.6 和1.7中都没有这个函数了):
在ajaxfileupload.js文件中添加如下代码:1234567891011handleError: function( s, xhr, status, e ) {// If a local callback was specified, fire itif ( s.error ) {s.error.call( s.context || s, xhr, status, e );}// Fire the global callbackif ( s.global ) {(s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );}}b.文件上传成功后,js将不会回调
success:{}
中的方法;
解决方法:
在ajaxfileupload.js文件中添加如下代码:123456789101112131415uploadHttpData: function( r, type ) {var data = !type;data = type == "xml" || data ? r.responseXML : r.responseText;// If the type is "script", eval it in global contextif ( type == "script" )jQuery.globalEval( data );// Get the JavaScript object, if JSON is used.if ( type == "json" )data = jQuery.parseJSON(jQuery(data).text());// evaluate scripts within htmlif ( type == "html" )jQuery("<div>").html(data).evalScripts();//alert($('param', data).each(function(){alert($(this).attr('value'));}));return data;}
- 前端页面的实现
在该实现中,javascript的元素fileElementId: "file"
表示需上传的文件的控件id,即html代码中的<input type="file" name="file" id="file"/>
,该javascript代码即获取id为file的文件进行上传操作;1234567891011121314151617181920212223242526272829303132333435<html><body><div><label>文件:</label><input type="file" name="file" id="file"/></div></body><script type="text/javascript" src="/assets/js/jquery-1.12.4.min.js"></script><script type="text/javascript" src="/assets/js/upload/ajaxfileupload.js"></script><script>function ajaxFileUpload() {$.ajaxFileUpload({url: "/upload",secureuri: false,data: {tag: version},fileElementId: "file",dataType: "json",success: function (data) {if (data && data.status == 0) {//上传成功} else {// 上传失败}},error {// 处理异常}});}</script></html>