周所周知,如果要提交的form表单内带有附件,那么需要设置属性enctype="multipart/form-data"
当我们要实现页面不刷新提交form表单的时候需要用到ajax,但是ajax提交form表单的时候需要将表单值进行序列化操作($(formId).formSerialize())。
所以问题出现了,表单序列化后form表单内的文件在后台就接不到了。
所以带有附件的form表单不能用ajax提交。既然我们要实现页面不刷新,那就需要模拟ajax进行提交form表单。
我是用隐藏的iframe实现的:
前提条件:
springmvc配置文件中加上 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
需要jar包:ant-1.6.5.jar;commons-fileupload-1.2.2.jar;commons-io-2.0.1.jar
代码示例:
上传文件jsp页面:
<form id="form2" name="form2" target="hidden_frame" enctype="multipart/form-data" method="post" > <!--two end--> <h4 class="title_bg_b"> <span class="title_left">软件升级</span> </h4> <ul class="form_list_ul clear"> <li class="clear"> <span class="list_li_span">软件安装包:</span> <input type="file" id="file1" name="file1"/> <input type="button" name="button2" onclick="uploadFile()" class="blue_btn" value="上传" /><span id="msgspan"></span> <input type="button" name="button2" id="shengji" class="blue_btn" onclick="Upgrade()" title="正在实现" value="升级" /> </li> </ul> </form> <iframe name=‘hidden_frame‘ id="hidden_frame" style=‘display:none‘ width="99%"></iframe>
js函数:
function createPrompt(info){ var msgw,msgh,bordercolor; msgw=400;//提示窗口的宽度 msgh=100;//提示窗口的高度 titleheight=25//提示窗口标题高度 bordercolor="#336699";//提示窗口的边框颜色 titlecolor="#99CCFF";//提示窗口的标题颜色 var sWidth,sHeight; sWidth=document.body.offsetWidth;//浏览器工作区域内页面宽度 或使用 screen.width//屏幕的宽度 sHeight=screen.height;//屏幕高度(垂直分辨率) //背景层(大小与窗口有效区域相同,即当弹出对话框时,背景显示为放射状透明灰色) var bgObj=document.createElement("div");//创建一个div对象(背景层) //动态创建元素,这里创建的是 div //定义div属性,即相当于(相当于,但确不是,必须对对象属性进行定义 //<div id="bgDiv" style="position:absolute; top:0; background-color:#777; filter:progid:DXImagesTransform.Microsoft.Alpha(style=3,opacity=25,finishOpacity=75); opacity:0.6; left:0; width:918px; height:768px; z-index:10000;"></div> bgObj.setAttribute(‘id‘,‘bgDiv‘); bgObj.style.position="absolute"; bgObj.style.top="0"; bgObj.style.background="#777"; bgObj.style.filter="progid:DXImageTransform.Microsoft.Alpha(style=3,opacity=25,finishOpacity=75"; bgObj.style.opacity="0.6"; bgObj.style.left="0"; bgObj.style.width=sWidth + "px"; bgObj.style.height=sHeight + "px"; bgObj.style.zIndex = "10000"; document.body.appendChild(bgObj);//在body内添加该div对象 //创建一个div对象(提示框层) var msgObj=document.createElement("div") //定义div属性,即相当于 //<div id="msgDiv" align="center" style="background-color:white; border:1px solid #336699; position:absolute; left:50%; top:50%; font:12px/1.6em Verdana,Geneva,Arial,Helvetica,sans-serif; margin-left:-225px; margin-top:npx; width:400px; height:100px; text-align:center; line-height:25px; z-index:100001;"></div> msgObj.setAttribute("id","msgDiv"); msgObj.setAttribute("align","center"); msgObj.style.background="white"; msgObj.style.border="1px solid " + bordercolor; msgObj.style.position = "absolute"; msgObj.style.left = "50%"; msgObj.style.top = "50%"; msgObj.style.font="12px/1.6em Verdana, Geneva, Arial, Helvetica, sans-serif"; msgObj.style.marginLeft = "-225px" ; msgObj.style.marginTop = -75+document.documentElement.scrollTop+"px"; msgObj.style.width = msgw + "px"; msgObj.style.height =msgh + "px"; msgObj.style.textAlign = "center"; msgObj.style.lineHeight ="25px"; msgObj.style.zIndex = "10001"; document.body.appendChild(msgObj);//在body内添加提示框div对象msgObj var txt=document.createElement("p");//创建一个p对象(提示框提示信息) //定义p的属性,即相当于 //<p style="margin:1em 0;" id="msgTxt">测试效果</p> txt.style.margin="1em 0" txt.setAttribute("id","msgTxt"); txt.innerHTML=info;//来源于函数调用时的参数值 document.getElementById("msgDiv" ).appendChild(txt);//在提示框div中添加提示信息对象txt var img=document.createElement("img"); img.src="/resources/images/waiting.gif"; img.style.width="150"; img.style.height="25"; img.style.align="center"; document.getElementById("msgDiv").appendChild(img); }
后台控制类:
package com.bohui.ipview.common; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.bohui.ipview.bean.FileUploadBean; /** * * @author caohaicheng * @date 2014-3-20 上午11:56:35 */ @Controller @RequestMapping(value = "fileOperate") public class FileOperateController { /** * 上传文件 * * @author caohaicheng * @date 2014-3-20 上午11:56:35 * @param request * @return * @throws Exception */ @RequestMapping(value = "upload1") public ModelAndView upload(HttpServletRequest request) throws Exception { ModelAndView mv=new ModelAndView("sysconfig/fileUploadResult"); FileUploadBean fup = new FileUploadBean(); fup=FileOperateUtil.upload(request ); mv.addObject("fileName",fup.getFileName() ); mv.addObject("fileSize",fup.getFileSize() ); mv.addObject("FileCreateDate", fup.getFileCreateDate()); mv.addObject("returnDesc", fup.getReturnDesc()); mv.addObject("returnFlag",fup.getReturnFlag() ); return mv; } /** * 下载 * * @author caohaicheng * @date 2014-3-20 上午11:56:35 * @param attachment * @param request * @param response * @return * @throws Exception */ @RequestMapping(value = "download") public ModelAndView download(HttpServletRequest request, HttpServletResponse response) throws Exception { String storeName = "201205051340364510870879724.zip"; String realName = "Java设计模式.zip"; String contentType = "application/octet-stream"; FileOperateUtil.download(request, response, storeName, contentType, realName); return null; } }
实现类:
package com.bohui.ipview.common; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.util.FileCopyUtils; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import com.bohui.ipview.bean.FileUploadBean; import com.bohui.ipview.util.DateTimeUtil; /** * * @author caohaicheng * @date 2014-3-20 上午11:56:35 */ public class FileOperateUtil { private static final String UPLOADDIR = "/bh/update/";// 上传后放在哪个位置(linux) private static final String UPLOADDIR1 = "/bh/backup/";// 上传后放在哪个位置(linux) /** * 将上传的文件进行重命名 * * @author caohaicheng * @date 2014-3-20 上午11:56:35 * @param name * @return */ private static String rename(String name) { Long now = Long.parseLong(new SimpleDateFormat("yyyyMMddHHmmss") .format(new Date())); Long random = (long) (Math.random() * now); String fileName = now + "" + random; if (name.indexOf(".") != -1) { fileName += name.substring(name.lastIndexOf(".")); } return fileName; } /** * 压缩后的文件名 * * @author caohaicheng * @date 2014-3-20 上午11:56:35 * @param name * @return */ private static String zipName(String name) { String prefix = ""; if (name.indexOf(".") != -1) { prefix = name.substring(0, name.lastIndexOf(".")); } else { prefix = name; } return prefix + ".zip"; } /** * 上传文件 * * @author caohaicheng * @date 2014-3-20 上午11:56:35 * @param request * @param params * @param values * @return * @throws Exception */ public static FileUploadBean upload(HttpServletRequest request) throws Exception { FileUploadBean fup = new FileUploadBean(); MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request; Map<String, MultipartFile> fileMap = mRequest.getFileMap(); //String uploadDir = request.getSession().getServletContext().getRealPath("/")+ FileOperateUtil.UPLOADDIR; //上传至相对路径 String uploadDir = FileOperateUtil.UPLOADDIR; //上传至绝对路径 String uploadDir1 = FileOperateUtil.UPLOADDIR1; //上传至绝对路径,这个是备份文件夹 File file = new File(uploadDir); File file1 = new File(uploadDir1); //如果不存在该路径就创建 if (!file.exists()) { file.mkdir(); } if (!file1.exists()) { file1.mkdir(); } delAllFile(uploadDir); //删除完里面所有内容 String fileName = null; int i = 0; for (Iterator<Map.Entry<String, MultipartFile>> it = fileMap.entrySet() .iterator(); it.hasNext(); i++) { Map.Entry<String, MultipartFile> entry = it.next(); MultipartFile mFile = entry.getValue(); fileName = mFile.getOriginalFilename();//获得文件名字 //String storeName = rename(fileName);//对文件进行重命名 String noZipName = uploadDir + fileName;//文件路径 String noZipName1 = uploadDir1 + fileName; File uploadFile = new File(noZipName); File uploadFile1 = new File(noZipName1); //String zipName = zipName(noZipName);//获得压缩后的文件名字 // 上传成为压缩文件 /* ZipOutputStream outputStream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(noZipName))); outputStream.putNextEntry(new ZipEntry(fileName)); outputStream.setEncoding("GBK"); FileCopyUtils.copy(mFile.getInputStream(), outputStream); */ try { FileCopyUtils.copy(mFile.getBytes(), uploadFile); } catch (Exception e) { fup.setReturnDesc("升级文件上传失败"); fup.setReturnFlag(false); e.printStackTrace(); return fup; } try { FileCopyUtils.copy(mFile.getBytes(), uploadFile1); } catch (Exception e) { fup.setReturnDesc("升级文件备份失败"); fup.setReturnFlag(false); e.printStackTrace(); return fup; } fup.setReturnFlag(true); fup.setFileName(fileName); fup.setFileCreateDate(DateTimeUtil.nowToString()); fup.setFileSize( new File(noZipName).length()); } return fup; } /** * 下载 * * @author caohaicheng * @date 2014-3-20 上午11:56:35 * @param request * @param response * @param storeName * @param contentType * @param realName * @throws Exception */ public static void download(HttpServletRequest request, HttpServletResponse response, String storeName, String contentType, String realName) throws Exception { response.setContentType("text/html;charset=UTF-8"); request.setCharacterEncoding("UTF-8"); BufferedInputStream bis = null; BufferedOutputStream bos = null; String ctxPath = request.getSession().getServletContext() .getRealPath("/") + FileOperateUtil.UPLOADDIR; String downLoadPath = ctxPath + storeName; long fileLength = new File(downLoadPath).length(); response.setContentType(contentType); response.setHeader("Content-disposition", "attachment; filename=" + new String(realName.getBytes("utf-8"), "ISO8859-1")); response.setHeader("Content-Length", String.valueOf(fileLength)); bis = new BufferedInputStream(new FileInputStream(downLoadPath)); bos = new BufferedOutputStream(response.getOutputStream()); byte[] buff = new byte[2048]; int bytesRead; while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) { bos.write(buff, 0, bytesRead); } bis.close(); bos.close(); } //删除指定文件夹下所有文件 //param path 文件夹完整绝对路径 public static boolean delAllFile(String path) { boolean flag = false; File file = new File(path); if (!file.exists()) { return flag; } if (!file.isDirectory()) { return flag; } String[] tempList = file.list(); File temp = null; for (int i = 0; i < tempList.length; i++) { if (path.endsWith(File.separator)) { temp = new File(path + tempList[i]); } else { temp = new File(path + File.separator + tempList[i]); } if (temp.isFile()) { temp.delete(); } if (temp.isDirectory()) { delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件 flag = true; } } return flag; } }
package com.bohui.ipview.bean; public class FileUploadBean { private String fileName; private Long fileSize; private String FileCreateDate; private String returnDesc; private Boolean returnFlag; public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public String getFileCreateDate() { return FileCreateDate; } public void setFileCreateDate(String fileCreateDate) { FileCreateDate = fileCreateDate; } public String getReturnDesc() { return returnDesc; } public void setReturnDesc(String returnDesc) { this.returnDesc = returnDesc; } public Boolean getReturnFlag() { return returnFlag; } public void setReturnFlag(Boolean returnFlag) { this.returnFlag = returnFlag; } public long getFileSize() { return fileSize; } public void setFileSize(long l) { this.fileSize = l; } }
子页面jsp文件fileUploadResult.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript"> function parentTishi(){ parent.tishi("${fileName}","${fileSize}","${FileCreateDate}","${returnDesc}","${returnFlag}"); } </script> </head> <body onload="parentTishi()" > 这里是上传文件的返回页面..... </body> </html>