项目中遇到要使用ajax提交包含file输入框的表单的情况,网上查了下,发现ajaxFileUpload.js插件的比较多。就研究了下,发现真的不错。
传统的包含file输入框的表单提交遇到的问题:
1.表单要添加“enctype=multipart/form-data”,这样后台就无法像普通表单提交那样通过request.getParameter(name)来获得用户提交的参数。
2.表单一定要使用submit提交,不能使用ajax将表单信息序列化异步提交。这样就导致了不能实现提交结果的异步刷新和响应。
//传统表单的ajax序列化异步提交 artDialog.confirm('确认要保存用户信息?',function(){ $.ajax({ type: "POST", url:$("#form").attr("action"), data:$('#form').serialize(),// 要提交的表单 dataType:'json', success: function(data) { if(data){ artDialog.alert(data.message); if(data.succeed == true){ gotoView('<%=path%>/userManage/getlist.do'); } } } }); });
ajaxFileUpload的使用:
1.js的引入
<script src="<%=path%>/resource/js/jquery.js"></script> <script type="text/javascript" src="<%=path%>/js/ajaxfileupload.js"></script>
2.file文本框,不受enctype=multipart/form-data的限制,可单独提交
<img src="<%=path%>/resource/images/sex1.png" id="personImage" style="width:160px;height:204px;"> <input id="fileToUpload" type="file" name="fileToUpload" class="input"> <a href="Javascript:void(0);" οnclick="ajaxFileUpload();">上传头像</a>
3.js上传代码——核心
$.ajaxFileUpload({ url : '<%=path%>/userManage/fileToUpload.do', secureuri : false, fileElementId : 'fileToUpload',// 上传控件的id dataType : 'json', success : function(data, status) { if(data.message) { alert(data.message); } if(data.succeed == true){ $("#personImage").attr("src", "<%=path%>/userManage/previewImage.do?r="+Math.random());//改变图片显示 } }, error : function(data, status, e) { alert('上传出错'); } });
4.spring mvc上传文件的配置文件spring-MVC.xml
<!-- 配置文件上传 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8"> <property name="maxUploadSize"> <value>104857600</value> </property> <property name="maxInMemorySize"> <value>4096</value> </property> </bean>
5.控制层接受上传文件
//头像上传 @RequestMapping(value="/fileToUpload.do") public void fileToUpload(@RequestParam("fileToUpload") MultipartFile myfile,HttpServletRequest request,HttpServletResponse response,HttpSession session){ try { /*System.out.println("文件原名: " + myfile.getOriginalFilename()); System.out.println("文件名称: " + myfile.getName()); System.out.println("文件长度: " + myfile.getSize()); System.out.println("文件类型: " + myfile.getContentType()); System.out.println("========================================");*/ long size = myfile.getSize();//文件大小 String orgFilename = myfile.getOriginalFilename(); String name = myfile.getName();//input的name String contentType = myfile.getContentType(); PrintWriter writer = response.getWriter(); response.setCharacterEncoding("UTF-8");//这两句是必须的,一定要加 response.setContentType("text/html;charset=UTF-8"); if(size>1024*1024){ jsonMap.put("succeed",false); jsonMap.put("message","图片大小不能超过1M!"); writer.print("{succeed:false,message:\"图片大小不能超过1M!\"}"); }else{ session.setAttribute("myfileDate", myfile.getBytes()); writer.print("{");//username //writer.print("succeed:true,message:\"文件大小:"+myfile.getSize()+",文件名:"+myfile.getName()+"\""); writer.print("succeed:true,message:\"文件上传成功!\""); writer.print("}"); } writer.close(); } catch (Exception e) { e.printStackTrace(); } }
6.获得保存到session中的图片信息
//获得上传到session中的图片信息 @RequestMapping(value="/previewImage.do") public void previewImage(HttpServletRequest request,HttpServletResponse response,HttpSession session){ try { byte[] photo= (byte[]) session.getAttribute("myfileDate"); if(photo!=null){ OutputStream os = response.getOutputStream(); InputStream is = new ByteArrayInputStream(photo); byte buf[] = new byte[1024]; while ((is.read(buf)) != -1) { os.write(buf); } is.close(); os.close(); } } catch (Exception e) { e.printStackTrace(); } }
遇到的问题:
1.上传文件失败时,不能进入 $.ajaxFileUpload中的error中,在火狐下查看,出现js报错。
解决方法:这是由于有些版本的jQuery中不包含handleError方法导致的,解决方式是在ajaxFileUpload.js中加入下面的代码:
handleError: function( s, xhr, status, e ) { if ( s.error ) { s.error.call( s.context || s, xhr, status, e ); } if ( s.global ) { (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] ); } }
2.ie9下明明网络请求返回的是200,但是总是提示上传文件失败;而ie8下弹窗提示出现了乱码。
解决方法:给response设置返回字符编码格式
response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8");