jquery 插件ajaxfileupload与struts2结合 实现异步上传图片
因为项目需要,想实现一个异步上传图片的功能。当然这时struts2自带的fileupload拦截器不能用了。
网上搜了下,基本都是用插件来实现了,我就随便选择了一个简单的插件-ajaxfileupload来实现、
先构架出struts2的框架就不说了,无非那5个常用的jar包导入而已。因为是jquery的插件,因此需要添加jquery库文件以及核心文件ajaxfileupload.js,下面附件中会有这个js文件。写一个相当简单的上传类:
java代码:
1 package com.aokunsang.action; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 7 import org.apache.struts2.ServletActionContext; 8 9 import com.opensymphony.xwork2.ActionSupport; 10 11 public class FileUploadAction extends ActionSupport { 12 13 private File file; 14 private String fileFileContentType; 15 private String fileFileName; 16 17 public void upload() throws Exception{ 18 String message = ""; 19 //这里的返回类型设置是重点。否则会报错,必须设置成text/html;如果设置成application/json IE下会有问题,chrome没问题的。 20 ServletActionContext.getResponse().setContentType("text/html;charset=utf-8"); 21 ServletActionContext.getResponse().setCharacterEncoding("utf-8"); 22 if(fileFileName.endsWith(".exe")){ 23 message = "不允许上传此类文件!"; 24 }else if(!file.exists()){ 25 message = "此文件不存在!"; 26 }else { 27 FileInputStream fis = new FileInputStream(file); 28 FileOutputStream fos = new FileOutputStream(new File("F://aa.jpg")); 29 byte bt[] = new byte[500]; 30 while(fis.read(bt)>0){ 31 fos.write(bt); 32 } 33 fis.close(); 34 fos.flush(); 35 fos.close(); 36 message = "文件上传成功!"; 37 } 38 ServletActionContext.getResponse().getWriter().write("{msg:\""+message+"\"}"); 39 ServletActionContext.getResponse().getWriter().flush(); 40 ServletActionContext.getResponse().getWriter().close(); 41 } 42 43 setter和getter。。。。
Xml代码:
1 <package namespace="/" name="root" extends="struts-default"> 2 <action name="fileUpload" class="com.aokunsang.action.FileUploadAction" method="upload"> 3 </action> 4 </package>
这里大家可能注意到:我的action中的方法没有返回值,因为我用ServletActionContext.getResponse().getWriter().write()直接返回给jquery回调函数需要的参数,所以没用struts2
的必须返回值,当然你也可以有返回值none等。
重点解析:
1、网上有说需要用struts-json.jar,我观察发现他们使用这个jar文件无非是想返回jquery的回调函数一个json字符串【切记是个字符串】而已。因此我使用:ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");
2、注意返回字符串的格式:必须是一个json格式的字符串,并且为"{msg:''}"这样类型。
3、当使用springMVC3.x时候,会使用@ResponseBody返回个json字符串,contentType为application/json类型,经测试,发现chrome正常;IE下会有问题(IE下得到的json字符串是:<PRE>json字符串</PRE>【带有PRE标签,不知道啥玩意原因】)。解决方法:只要把contentType设置成text/html就行。给个例子:
Java代码:
1 @RequestMapping(value="uploadImage",method=RequestMethod.POST) 2 public void uploadImage(HttpServletResponse response,MultipartFile imgFile,String imgFlag,String companyid) throws IOException{ 3 4 ...... 5 6 Map<String,String> resultParam = new HashMap<String,String>(); 7 resultParam.put("msg", msg); 8 resultParam.put("error", error); 9 response.setContentType("text/html"); 10 ObjectMapper objectMapper = new ObjectMapper(); 11 JsonGenerator generator = objectMapper.getJsonFactory().createJsonGenerator(response.getOutputStream(),JsonEncoding.UTF8); //设置JSON编码格式 12 objectMapper.writeValue(generator, resultParam); 13 }
可参考:http://fujiangyong2009.blog.163.com/blog/static/126217857201292510823706/
----------------------------------------------------------------------------------------------------------------------------------
网上有很多人问,ajaxfileupload是否可以添加自定义参数支持,我的回答是:完全可以。只不过需要我们手动自己添加这样的支持,看了源代码,它也是封装了一个form表单,
咱们把需要的参数添加进去不就大功告成了嘛、说整就整、看代码:
Js代码:
1 。。。。上略 2 createUploadForm: function(id, fileElementId, data) 3 { 4 //create form 5 var formId = 'jUploadForm' + id; 6 var fileId = 'jUploadFile' + id; 7 var form = $('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>'); 8 var oldElement = $('#' + fileElementId); 9 var newElement = $(oldElement).clone(); 10 $(oldElement).attr('id', fileId); 11 $(oldElement).before(newElement); 12 $(oldElement).appendTo(form); 13 //添加参数支持 14 if(data){ 15 $.each(data,function(key,value){ 16 $("<input type='hidden' name='"+key+"' value='"+value+"'/>").appendTo(form); 17 }) 18 } 19 //set attributes 20 $(form).css('position', 'absolute'); 21 $(form).css('top', '-1200px'); 22 $(form).css('left', '-1200px'); 23 $(form).appendTo('body'); 24 return form; 25 }, 26 。。。。。。下略
Js代码:
1 ajaxFileUpload: function(s) { 2 // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout 3 s = jQuery.extend({}, jQuery.ajaxSettings, s); 4 var id = new Date().getTime() 5 var form = jQuery.createUploadForm(id, s.fileElementId,s.data); 6 var io = jQuery.createUploadIframe(id, s.secureuri); 7 var frameId = 'jUploadFrame' + id; 8 var formId = 'jUploadForm' + id; 9 // Watch for a new set of requests 10 if ( s.global && ! jQuery.active++ ) 11 { 12 jQuery.event.trigger( "ajaxStart" ); 13 }