java ssm框架实现文件上传
实现:单文件上传、多文件上传(单选和多选),并且用 ajax 异步刷新,在当前界面显示上传的文件
首先springmvc的配置文件要配置上传文件解析器:
1 <!-- 配置文件解析器 --> 2 <bean id="multipartResolver" 3 class="org.springframework.web.multipart.commons.CommonsMultipartResolver" 4 p:defaultEncoding="utf-8"> 5 <property name="uploadTempDir" value="/temp"></property> 6 <property name="maxUploadSize"> 7 <value>209715200</value><!-- 200MB --> 8 </property> 9 <property name="maxInMemorySize"> 10 <value>4096</value><!-- 4KB大小读写 --> 11 </property> 12 </bean>
其次在pom.xml中要配置两个上传文件的依赖
1 <!--上传文件相关的jar包 --> 2 <dependency> 3 <groupId>commons-io</groupId> 4 <artifactId>commons-io</artifactId> 5 <version>2.4</version> 6 </dependency> 7 8 <dependency> 9 <groupId>commons-fileupload</groupId> 10 <artifactId>commons-fileupload</artifactId> 11 <version>1.3.1</version> 12 </dependency> 13 14 <dependency> 15 <groupId>org.apache.commons</groupId> 16 <artifactId>commons-lang3</artifactId> 17 <version>3.3.2</version> 18 </dependency>
单文件上传:
1 /** 2 * 单文件上传 3 * @param file 4 * @param request 5 * @return 6 * @throws IllegalStateException 7 * @throws IOException 8 * @throws JSONException 9 */ 10 public static String simUpload(MultipartFile file, HttpServletRequest request) 11 throws IllegalStateException, IOException, JSONException{ 12 13 if(!file.isEmpty()){ 14 String path = request.getSession().getServletContext().getRealPath("/upload"); 15 //定义文件 16 File parent = new File(path); 17 if(!parent.exists()) parent.mkdirs(); 18 19 HashMap<String, Object> map = new HashMap<String,Object>(); 20 21 String oldName = file.getOriginalFilename(); 22 23 long size = file.getSize(); 24 25 //使用TmFileUtil文件上传工具获取文件的各种信息 26 //优化文件大小 27 String sizeString = TmFileUtil.countFileSize(size); 28 //获取文件后缀名 29 String ext = TmFileUtil.getExtNoPoint(oldName); 30 //随机重命名,10位时间字符串 31 String newFileName = TmFileUtil.generateFileName(oldName, 10, "yyyyMMddHHmmss"); 32 33 String url = "upload/"+newFileName; 34 35 //文件传输,parent文件 36 file.transferTo(new File(parent, newFileName)); 37 38 map.put("oldname",oldName);//文件原名称 39 map.put("ext",ext); 40 map.put("size",sizeString); 41 map.put("name",newFileName);//文件新名称 42 map.put("url",url); 43 44 //以json方式输出到页面 45 return JSONUtil.serialize(map); 46 }else{ 47 return null; 48 } 49 }
多文件上传(整合了 单选文件和多选文件 的两种)
1 /** 2 * 多文件上传 3 * @param files 4 * @param request 5 * @return 6 * @throws IllegalStateException 7 * @throws IOException 8 * @throws JSONException 9 */ 10 public static List<HashMap<String, Object>> mutlUpload(MultipartFile[] files, HttpServletRequest request) 11 throws IllegalStateException, IOException, JSONException{ 12 13 if(files.length > 0){ 14 String path = request.getSession().getServletContext().getRealPath("/upload"); 15 //定义文件 16 File parent = new File(path); 17 if(!parent.exists()) parent.mkdirs(); 18 19 //创建这个集合保存所有文件的信息 20 List<HashMap<String, Object>> listMap = new ArrayList<HashMap<String, Object>>(); 21 22 //循环多次上传多个文件 23 for (MultipartFile file : files) { 24 25 //创建map对象保存每一个文件的信息 26 HashMap<String, Object> map = new HashMap<String,Object>(); 27 28 String oldName = file.getOriginalFilename(); 29 30 long size = file.getSize(); 31 32 //使用TmFileUtil文件上传工具获取文件的各种信息 33 //优化文件大小 34 String sizeString = TmFileUtil.countFileSize(size); 35 //获取文件后缀名 36 String ext = TmFileUtil.getExtNoPoint(oldName); 37 //随机重命名,10位时间字符串 38 String newFileName = TmFileUtil.generateFileName(oldName, 10, "yyyyMMddHHmmss"); 39 40 String url = "upload/"+newFileName; 41 42 //文件传输,parent文件 43 file.transferTo(new File(parent, newFileName)); 44 45 map.put("oldname",oldName);//文件原名称 46 map.put("ext",ext); 47 map.put("size",sizeString); 48 map.put("name",newFileName);//文件新名称 49 map.put("url",url); 50 51 listMap.add(map); 52 } 53 54 //以json方式输出到页面 55 return listMap; 56 }else{ 57 return null; 58 } 59 }
前端代码:
文件多选,实际上在
<input type="file" class="fileupon33" name="fileupmulti" accept="image/jpeg,image/png" onchange="mutiFiles(this)" multiple/>
多加了一个 multiple 属性。
要想在当前界面显示上传的文件,而不跳转,就利用 ajax 异步请求:
不过需要注意的是,我这里使用 FormData() 储存文件对象, ajax 要配上这几个参数才可实现文件上传:
$.ajax({
type:"post",
data:form, //FormData()对象
url:basePath+"/upload/mutl",
contentType: false, //必须false才会自动加上正确的Content-Type
processData: false, //必须false才会避开jQuery对 formdata 的默认处理 , XMLHttpRequest会对 formdata 进行正确的处理
success:function(data){
}
});
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+path+"/"; 5 pageContext.setAttribute("basePath", basePath); 6 %> 7 <!DOCTYPE HTML> 8 <html> 9 <head> 10 <title>文件上传</title> 11 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 12 <meta name="keywords" content="keyword1,keyword2,keyword3"> 13 <meta name="description" content="This is my page"> 14 <style> 15 *{padding: 0;margin:0} 16 ul,li{list-style:none;} 17 a{color:#333;text-decoration: none;} 18 .hidden{display:hidden;} 19 input{border:0;outline:0;margin-bottom:10px;} 20 img{vertical-align: middle;} 21 .clear{clear:both;} 22 body{font-size:14px;font-family: "微软雅黑";background:#333} 23 .buttons{ display: block; 24 width: 80px; 25 height: 26px; 26 color: black; 27 background: #ffffff; 28 font-size: 14px; 29 font-family: "微软雅黑"; 30 margin: 0 auto; 31 cursor: pointer; 32 margin-bottom: 10px;} 33 34 .container{width:1080px;margin:80px auto;} 35 36 .formbox{float:left;text-align:center;width:300px;} 37 .title{color:#fff;font-size:24px;margin-bottom:20px;} 38 .formbox .f_btn{width:100px;height:40px;background:#0c0;color:#fff;font-size:14px;font-family:"微软雅黑";cursor:pointer;font-weight:bold;} 39 .massage p{color:#fff;text-align:left;height:24px;} 40 .sinimg{width:300px;height:300px;line-height:300px;color:#fff;} 41 42 .formmutibox{float:left;width: 342px;margin: 0 24px 0;text-align:center;} 43 .formmutibox .title{color:#fff;font-size:24px;margin-bottom:20px;} 44 .formmutibox .f_btn{width:100px;height:40px;background:#0c0;color:#fff;font-size:14px;font-family:"微软雅黑";cursor:pointer;font-weight:bold;} 45 .files table td{color:#fff;width:135px;} 46 47 ::-webkit-scrollbar{width: 10px;height: 10px;} 48 ::-webkit-scrollbar-track{background: 0 0;} 49 ::-webkit-scrollbar-track-piece{background:#fff;} 50 ::-webkit-scrollbar-thumb{background-color: #a2a2a2; border-radius: 5px;} 51 ::-webkit-scrollbar-thumb:hover{background-color: #868686;} 52 ::-webkit-scrollbar-corner{background:#212121;} 53 ::-webkit-scrollbar-resizer{background:#FF0BEE;} 54 scrollbar{-moz-appearance:none !important;background:rgb(0,255,0) !important;} 55 scrollbarbutton{-moz-appearance:none !important;background-color:rgb(0,0,255) !important;} 56 scrollbarbutton:hover{-moz-appearance:none !important;background-color:rgb(255,0,0) !important;} 57 /* 隐藏上下箭头 */ 58 scrollbarbutton{display:none !important;} 59 /* 纵向滚动条宽度 */ 60 scrollbar[orient="vertical"]{min-width:12px !important;} 61 </style> 62 </head> 63 <body> 64 <div class="container"> 65 <!--单文件上传--> 66 <div class="formbox"> 67 <p class="title">单个文件上传</p> 68 <input type="file" id="fileupone" name="fileup" accept="image/jpeg,image/png" onchange="uploadFile(this)"/> 69 <div class="massage"> 70 <p>文件名:<span class="filename"></span></p> 71 <p>大小:<span class="filesize"></span></p> 72 <p>文件格式:<span class="fileext"></span></p> 73 <p>预览:</p> 74 <div class="sinimg"> 75 预览图 76 </div> 77 </div> 78 </div> 79 80 <!--多文件上传--> 81 <div class="formmutibox"> 82 <p class="title">多文件上传(单选)</p> 83 <input type="file" class="fileupon11" accept="image/jpeg,image/png" /> 84 <input type="file" class="fileupon12" accept="image/jpeg,image/png" /> 85 <input type="file" class="fileupon13" accept="image/jpeg,image/png" /> 86 <input type="button" class="buttons" value="提交" onclick="multipartone()"/> 87 <!--files start--> 88 <div class="files"> 89 <table> 90 <thead> 91 <tr> 92 <td class="filelook2">文件预览</td> 93 <td class="filename2">文件名</td> 94 <td class="filesize2">大小</td> 95 </tr> 96 </thead> 97 <tbody id="f_tbody"> 98 </tbody> 99 </table> 100 </div> 101 </div> 102 103 <!--多文件上传--> 104 <div class="formmutibox"> 105 <p class="title">多文件上传(多选)</p> 106 <input type="file" class="fileupon33" name="fileupmulti" accept="image/jpeg,image/png" onchange="mutiFiles(this)" multiple/> 107 <!--files start--> 108 <div class="files"> 109 <table> 110 <thead> 111 <tr> 112 <td class="filelook33">文件预览</td> 113 <td class="filename33">文件名</td> 114 <td class="filesize33">大小</td> 115 </tr> 116 </thead> 117 <tbody id="f_tbody_m"> 118 </tbody> 119 </table> 120 </div> 121 </div> 122 <div class="clear"></div> 123 </div> 124 125 <script type="text/javascript" src="${basePath}/resource/js/jquery-1.11.3.min.js"></script> 126 <script type="text/javascript">var basePath = "${basePath}";</script> 127 <script type="text/javascript"> 128 129 //单文件上传 130 function uploadFile(obj){ 131 //创建一个FormData对象:用一些键值对来模拟一系列表单控件:即把form中所有表单元素的name与value组装成一个queryString 132 var form = new FormData(); 133 var fileObj = obj.files[0]; 134 form.append("doc",fileObj); 135 136 $.ajax({ 137 type:"post", 138 data:form, 139 url:basePath+"/upload/file", 140 contentType: false, //必须false才会自动加上正确的Content-Type 141 /* 142 必须false才会避开jQuery对 formdata 的默认处理 143 XMLHttpRequest会对 formdata 进行正确的处理 144 */ 145 processData: false, 146 success:function(data){ 147 var jdata = eval("("+data+")"); 148 $(".filename").text(jdata.oldname); 149 $(".filesize").text(jdata.size); 150 $(".fileext").text(jdata.ext); 151 var imgString = "<img alt='预览图' src='"+jdata.url+"' width='300'>"; 152 $(".sinimg").html(imgString); 153 //清除文件表单 154 $("#fileupone").val(""); 155 } 156 }); 157 } 158 159 //多文件上传(单选) 160 function multipartone(){ 161 var file1 = $(".fileupon11").get(0).files[0]; 162 var file2 = $(".fileupon12").get(0).files[0]; 163 var file3 = $(".fileupon13").get(0).files[0]; 164 //如果都是空,则直接退出 165 if(isEmpty(file1) && isEmpty(file2) && isEmpty(file3)) return; 166 167 var form = new FormData(); 168 //用同一个名字,注入到controller层的参数数组 169 form.append("doc",file1); 170 form.append("doc",file2); 171 form.append("doc",file3); 172 173 $.ajax({ 174 type:"post", 175 data:form, 176 url:basePath+"/upload/mutl", 177 contentType: false, //必须false才会自动加上正确的Content-Type 178 /* 179 必须false才会避开jQuery对 formdata 的默认处理 180 XMLHttpRequest会对 formdata 进行正确的处理 181 */ 182 processData: false, 183 success:function(data){ 184 var len = data.length; 185 for(var i = 0;i < len;i++){ 186 var datajson = data[i]; 187 $("#f_tbody").append("<tr class='f_item'>"+ 188 "<td><img src='"+datajson.url+"' alt='预览图像' width='40' height='40' /></td>"+ 189 "<td>"+datajson.oldname+"</td>"+ 190 "<td>"+datajson.size+"</td>" 191 ); 192 } 193 //清除文件表单 194 $(".fileupon11").val(""); 195 $(".fileupon12").val(""); 196 $(".fileupon13").val(""); 197 } 198 }); 199 } 200 201 //多文件上传(多选) 202 function mutiFiles(obj){ 203 var form = new FormData(); 204 var fileObj = obj.files; 205 var length = fileObj.length; 206 //将fileObj转换成数组 207 //var filese = Array.from(fileObj); 208 for(var i = 0;i < length;i++){ 209 form.append("doc",fileObj[i]); 210 } 211 $.ajax({ 212 type:"post", 213 data:form, 214 url:basePath+"/upload/mutl", 215 contentType: false, //必须false才会自动加上正确的Content-Type 216 /* 217 必须false才会避开jQuery对 formdata 的默认处理 218 XMLHttpRequest会对 formdata 进行正确的处理 219 */ 220 processData: false, 221 success:function(data){ 222 var len = data.length; 223 for(var i = 0;i < len;i++){ 224 var datajson = data[i]; 225 $("#f_tbody_m").append("<tr class='f_item'>"+ 226 "<td><img src='"+datajson.url+"' alt='预览图像' width='40' height='40' /></td>"+ 227 "<td>"+datajson.oldname+"</td>"+ 228 "<td>"+datajson.size+"</td>" 229 ); 230 } 231 //清除文件表单 232 $(".fileupon33").val(""); 233 } 234 }); 235 } 236 237 /** 238 * 判断非空 239 * 240 * @param val 241 * @returns {Boolean} 242 */ 243 function isEmpty(val) { 244 val = $.trim(val); 245 if (val == null) 246 return true; 247 if (val == undefined || val == 'undefined') 248 return true; 249 if (val == "") 250 return true; 251 if (val.length == 0) 252 return true; 253 if (!/[^(^s*)|(s*$)]/.test(val)) 254 return true; 255 return false; 256 } 257 </script> 258 </body> 259 </html>
controller层调用:
1 package com.krry.controller; 2 3 import java.io.IOException; 4 import java.util.HashMap; 5 import java.util.List; 6 7 import javax.servlet.http.HttpServletRequest; 8 9 import org.apache.struts2.json.JSONException; 10 import org.springframework.stereotype.Controller; 11 import org.springframework.web.bind.annotation.RequestMapping; 12 import org.springframework.web.bind.annotation.RequestParam; 13 import org.springframework.web.bind.annotation.ResponseBody; 14 import org.springframework.web.multipart.MultipartFile; 15 16 import com.krry.util.UploadUtil; 17 18 /** 19 * 文件上传类 20 * KrryUploadController 21 * @author krry 22 * @version 1.0.0 23 * 24 */ 25 @Controller 26 @RequestMapping("/upload") 27 public class KrryUploadController { 28 29 /** 30 * 单文件上传 31 * @param file 32 * @param request 33 * @return 34 * @throws IllegalStateException 35 * @throws IOException 36 * @throws JSONException 37 */ 38 @ResponseBody 39 @RequestMapping(value = "/file") 40 public String krryupload(@RequestParam("doc") MultipartFile file, HttpServletRequest request) throws IllegalStateException, IOException, JSONException{ 41 42 //调用工具类完成上传,返回相关数据到页面 43 return UploadUtil.simUpload(file, request); 44 } 45 46 /** 47 * 多文件上传 48 * @param file 49 * @param request 50 * @return 51 * @throws IllegalStateException 52 * @throws IOException 53 * @throws JSONException 54 */ 55 // 这里的MultipartFile[] file表示前端页面上传过来的多个文件,file对应页面中多个file类型的input标签的name,但框架只会将一个文件封装进一个MultipartFile对象, 56 // 并不会将多个文件封装进一个MultipartFile[]数组,直接使用会报[Lorg.springframework.web.multipart.MultipartFile;.<init>()错误, 57 // 所以需要用@RequestParam校正参数(参数名与MultipartFile对象名一致),当然也可以这么写:@RequestParam("file") MultipartFile[] files。 58 @ResponseBody 59 @RequestMapping(value = "/mutl") 60 public List<HashMap<String, Object>> krryuploadMutl(@RequestParam("doc") MultipartFile[] file, HttpServletRequest request) throws IllegalStateException, IOException, JSONException{ 61 //调用工具类完成上传,返回相关数据到页面 62 return UploadUtil.mutlUpload(file, request); 63 } 64 }
到这里,完成 ajax异步请求文件上传 的功能。
附上优化文件大小的代码:
1 /** 2 * 将文件的字节数转换成文件的大小 3 * com.krry.uitl 4 * 方法名:format 5 * @author krry 6 * @param size 7 * @return String 8 * @exception 9 * @since 1.0.0 10 */ 11 public static String format(long size){ 12 float fsize = size; 13 String fileSizeString; 14 if (fsize < 1024) { 15 fileSizeString = String.format("%.2f", fsize) + "B"; //2f表示保留两位小数 16 } else if (fsize < 1048576) { 17 fileSizeString = String.format("%.2f", fsize/1024) + "KB"; 18 } else if (fsize < 1073741824) { 19 fileSizeString = String.format("%.2f", fsize/1024/1024) + "MB"; 20 } else if (fsize < 1024 * 1024 * 1024) { 21 fileSizeString = String.format("%.2f", fsize/1024/1024/1024) + "GB"; 22 } else { 23 fileSizeString = "0B"; 24 } 25 return fileSizeString; 26 }