转自: https://blessht.iteye.com/blog/1405057
最近自己在做一个小系统玩的时候涉及到了文件的上传,于是在网上找到Java上传文件的方案,最后确定使用common-fileupload实现上传操作。
- 需求说明
用户添加页面有一个“上传”按钮,点击按钮弹出上传界面,上传完成后关闭上传界面。
- 所需Jar包
commons.fileupload-1.2.0.jar、commons.logging-1.1.1.jar、commons.beanutils-1.8.0.jar、commons.collections-3.2.0.jar、commons.io-1.4.0.jar、commons.lang-2.1.0.jar
- 实现效果
- 代码实现
首先编写核心代码,Javascript打开上传页面,并且从上传页获取返回参数,最后数据返回给回调函数callback:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 7 <title>定义input type="file" 的样式</title> 8 <style type="text/css"> 9 body { 10 font-size: 14px; 11 } 12 13 input { 14 vertical-align: middle; 15 margin: 0; 16 padding: 0 17 } 18 19 .file-box { 20 position: relative; 21 340px 22 } 23 24 .txt { 25 height: 22px; 26 border: 1px solid #cdcdcd; 27 180px; 28 } 29 30 .btn { 31 background-color: #FFF; 32 border: 1px solid #CDCDCD; 33 height: 24px; 34 70px; 35 } 36 37 .file { 38 position: absolute; 39 top: 0; 40 right: 80px; 41 height: 24px; 42 filter: alpha(opacity : 0); 43 opacity: 0; 44 260px 45 } 46 </style> 47 <script> 48 /** 49 * 跳转到上传页 50 * functionId:功能ID 51 * fileType:文件类型 52 * maxSize:文件容量上限 53 * callback:回调函数,返回三个参数:文件真名、文件存放名和文件大小 54 用户添加页面相关代码,点击“上传”按钮时调用上面的核心js代码,并且获取返回值 55 */ 56 function openUpload(functionId, fileType, maxSize, callback) { 57 var url = root + "/CommonController.jhtml?method=goFileUpload&"; 58 if (functionId != null) { 59 url = url + "functionId=" + functionId + "&"; 60 } 61 if (fileType != null) { 62 url = url + "fileType=" + fileType + "&"; 63 } 64 if (maxSize != null) { 65 url = url + "maxSize=" + maxSize; 66 } 67 var win = window.showModalDialog(url, "", 68 "dialogWidth:300px;dialogHeight:150px;scroll:no;status:no"); 69 if (win != null) { 70 var arrWin = win.split(","); 71 callback(arrWin[0], arrWin[1], arrWin[2]); 72 } 73 } 74 <script> 75 ....... 76 77 function openUpload_(){ 78 openUpload(null,'JPG,GIF,JPEG,PNG','5',callback); 79 } 80 81 /** 82 * 回调函数,获取上传文件信息 83 * realName真实文件名 84 * saveName文件保存名 85 * maxSize文件实际大小 86 */ 87 function callback(realName,saveName,maxSize){ 88 $("#photo_").val(saveName); 89 //回调后其它操作 90 } 91 </script> 92 </script> 93 </head> 94 <body> 95 96 97 <div class="file-box"> 98 <tr> 99 <td>头像:</td> 100 <td><input type="hidden" name="photo" id="photo_"></input> <input 101 type="button" onclick="openUpload_();" value="上传" /></td> 102 </tr> 103 </div> 104 </body> 105 </html>
文件上传的JSP代码,需要注意的是在head标签内添加<base target="_self">以防止页面跳转时弹出新窗口,用户选择指定文件,点击上传时就提交表单访问指定后台代码
1 <%@ include file="/WEB-INF/jsp/header.jsp" %> 2 <%@ page language="java" contentType="text/html; charset=UTF-8" 3 pageEncoding="UTF-8"%> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 8 <meta http-equiv="pragma" content="no-cache" /> 9 <base target="_self"> 10 <title>文件上传</title> 11 </head> 12 <body> 13 <h5>文件上传</h5><hr/> 14 <form id="file_upload_id" name="file_upload_name" action="<%=root%>/CommonController.jhtml?method=doFileUpload" method="post" enctype="multipart/form-data"> 15 <input type="hidden" name="functionId" value="${functionId}"/> 16 <input type="hidden" name="fileType" value="${fileType}"/> 17 <input type="hidden" name="maxSize" value="${maxSize}"/> 18 <div><input type="file" name="file_upload"/></div> 19 <c:if test="${maxSize!=null}"> 20 <div style="font: 12">文件最大不能超过${maxSize}MB</div> 21 </c:if> 22 <c:if test="${fileType!=null}"> 23 <div style="font: 12">文件格式必须是:${fileType}</div> 24 </c:if> 25 <div><input type="submit" value="上传"/></div> 26 </form> 27 </body> 28 </html>
CommonController目前有两个方法,一个是跳转到上传页面的方法,一个是执行上传操作的方法doFileUpload,上传方法运行的大概逻辑是:首先获取页面的请求参数,fileType用于限制上传文件格式,
maxSize用于限制上传文件最大值,随后创建上传目录上传即可。
1 public class CommonController extends BaseController { 2 Log log = LogFactory.getLog(CommonController.class); 3 4 Properties fileUploadPro = null; 5 public CommonController(){ 6 fileUploadPro = PropertiesUtil.getPropertiesByClass("fileupload.properties"); 7 } 8 9 10 @Override 11 public ModeAndView init(HttpServletRequest request, 12 HttpServletResponse response) throws ServletException, IOException { 13 14 return null; 15 } 16 17 /** 18 * 跳转到文件上传页 19 * @param request 20 * @param response 21 * @return 22 * @throws ServletException 23 * @throws IOException 24 */ 25 public ModeAndView goFileUpload(HttpServletRequest request, 26 HttpServletResponse response) throws ServletException, IOException { 27 String functionId = request.getParameter("functionId"); 28 String fileType = request.getParameter("fileType"); 29 String maxSize = request.getParameter("maxSize"); 30 ModeAndView mav = new ModeAndView("/WEB-INF/jsp/common/fileUpload.jsp"); 31 32 if(functionId!=null && !"".equals(functionId.trim())){ 33 mav.addObject("functionId", functionId); 34 } 35 if(fileType!=null && !"".equals(fileType.trim())){ 36 mav.addObject("fileType", fileType); 37 } 38 if(maxSize!=null && !"".equals(maxSize.trim())){ 39 mav.addObject("maxSize", maxSize); 40 } 41 return mav; 42 } 43 44 /** 45 * 上传文件 46 * @param request 47 * @param response 48 * @return 49 * @throws ServletException 50 * @throws IOException 51 */ 52 @SuppressWarnings("unchecked") 53 public ModeAndView doFileUpload(HttpServletRequest request, 54 HttpServletResponse response) throws ServletException, IOException { 55 //获取并解析文件类型和支持最大值 56 String functionId = request.getParameter("functionId"); 57 String fileType = request.getParameter("fileType"); 58 String maxSize = request.getParameter("maxSize"); 59 60 //临时目录名 61 String tempPath = fileUploadPro.getProperty("tempPath"); 62 //真实目录名 63 String filePath = fileUploadPro.getProperty("filePath"); 64 65 FileUtil.createFolder(tempPath); 66 FileUtil.createFolder(filePath); 67 68 DiskFileItemFactory factory = new DiskFileItemFactory(); 69 //最大缓存 70 factory.setSizeThreshold(5*1024); 71 //设置临时文件目录 72 factory.setRepository(new File(tempPath)); 73 ServletFileUpload upload = new ServletFileUpload(factory); 74 if(maxSize!=null && !"".equals(maxSize.trim())){ 75 //文件最大上限 76 upload.setSizeMax(Integer.valueOf(maxSize)*1024*1024); 77 } 78 79 try { 80 //获取所有文件列表 81 List<FileItem> items = upload.parseRequest(request); 82 for (FileItem item : items) { 83 if(!item.isFormField()){ 84 //文件名 85 String fileName = item.getName(); 86 87 //检查文件后缀格式 88 String fileEnd = fileName.substring(fileName.lastIndexOf(".")+1).toLowerCase(); 89 if(fileType!=null && !"".equals(fileType.trim())){ 90 boolean isRealType = false; 91 String[] arrType = fileType.split(","); 92 for (String str : arrType) { 93 if(fileEnd.equals(str.toLowerCase())){ 94 isRealType = true; 95 break; 96 } 97 } 98 if(!isRealType){ 99 //提示错误信息:文件格式不正确 100 super.printJsMsgBack(response, "文件格式不正确!"); 101 return null; 102 } 103 } 104 105 //创建文件唯一名称 106 String uuid = UUID.randomUUID().toString(); 107 //真实上传路径 108 StringBuffer sbRealPath = new StringBuffer(); 109 sbRealPath.append(filePath).append(uuid).append(".").append(fileEnd); 110 //写入文件 111 File file = new File(sbRealPath.toString()); 112 item.write(file); 113 //上传成功,向父窗体返回数据:真实文件名,虚拟文件名,文件大小 114 StringBuffer sb = new StringBuffer(); 115 sb.append("window.returnValue='").append(fileName).append(",").append(uuid).append(".").append(fileEnd).append(",").append(file.length()).append("';"); 116 sb.append("window.close();"); 117 super.printJsMsg(response, sb.toString()); 118 log.info("上传文件成功,JS信息:"+sb.toString()); 119 }//end of if 120 }//end of for 121 122 }catch (Exception e) { 123 //提示错误:比如文件大小 124 super.printJsMsgBack(response, "上传失败,文件大小不能超过"+maxSize+"M!"); 125 log.error("上传文件异常!",e); 126 return null; 127 } 128 129 return null; 130 } 131 }
至此一个文件上传即已实现,而且能够基本满足不同模块的上传通用性,我还留着个functionId参数用于以后针对不同模块上传文件到不同目录。