博客地址:https://ainyi.com/76html
平常,工做前端
在这里总结一下上传吧(是之前作过的练习,就汇总到我的博客吧)java
java ssm 框架实现文件上传 实现:单文件上传、多文件上传(单选和多选),而且用 ajax 异步刷新,在当前界面显示上传的文件web
后端
首先 springmvc 的配置文件要配置上传文件解析器:ajax
<!-- 配置文件解析器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8"> <property name="uploadTempDir" value="/temp"></property> <property name="maxUploadSize"> <value>209715200</value><!-- 200MB --> </property> <property name="maxInMemorySize"> <value>4096</value><!-- 4KB大小读写 --> </property> </bean>
<br>spring
其次在 pom.xml 中要配置上传文件的依赖apache
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.3.2</version> </dependency>
<br>json
单文件上传后端
/** * 单文件上传 * @param file * @param request * @return * @throws IllegalStateException * @throws IOException * @throws JSONException */ public static String simUpload(MultipartFile file, HttpServletRequest request) throws IllegalStateException, IOException, JSONException{ if(!file.isEmpty()){ String path = request.getSession().getServletContext().getRealPath("/upload"); //定义文件 File parent = new File(path); if(!parent.exists()) parent.mkdirs(); HashMap<String, Object> map = new HashMap<String,Object>(); String oldName = file.getOriginalFilename(); long size = file.getSize(); //使用TmFileUtil文件上传工具获取文件的各类信息 //优化文件大小 String sizeString = TmFileUtil.countFileSize(size); //获取文件后缀名 String ext = TmFileUtil.getExtNoPoint(oldName); //随机重命名,10位时间字符串 String newFileName = TmFileUtil.generateFileName(oldName, 10, "yyyyMMddHHmmss"); String url = "upload/"+newFileName; //文件传输,parent文件 file.transferTo(new File(parent, newFileName)); map.put("oldname",oldName);//文件原名称 map.put("ext",ext); map.put("size",sizeString); map.put("name",newFileName);//文件新名称 map.put("url",url); //以json方式输出到页面 return JSONUtil.serialize(map); }else{ return null; } }
<br>数组
多文件上传(整合了==单选文件==和==多选文件==的两种)
/** * 多文件上传 * @param files * @param request * @return * @throws IllegalStateException * @throws IOException * @throws JSONException */ public static List<HashMap<String, Object>> mutlUpload(MultipartFile[] files, HttpServletRequest request) throws IllegalStateException, IOException, JSONException{ if(files.length > 0){ String path = request.getSession().getServletContext().getRealPath("/upload"); //定义文件 File parent = new File(path); if(!parent.exists()) parent.mkdirs(); //建立这个集合保存全部文件的信息 List<HashMap<String, Object>> listMap = new ArrayList<HashMap<String, Object>>(); //循环屡次上传多个文件 for (MultipartFile file : files) { //建立map对象保存每个文件的信息 HashMap<String, Object> map = new HashMap<String,Object>(); String oldName = file.getOriginalFilename(); long size = file.getSize(); //使用TmFileUtil文件上传工具获取文件的各类信息 //优化文件大小 String sizeString = TmFileUtil.countFileSize(size); //获取文件后缀名 String ext = TmFileUtil.getExtNoPoint(oldName); //随机重命名,10位时间字符串 String newFileName = TmFileUtil.generateFileName(oldName, 10, "yyyyMMddHHmmss"); String url = "upload/"+newFileName; //文件传输,parent文件 file.transferTo(new File(parent, newFileName)); map.put("oldname",oldName);//文件原名称 map.put("ext",ext); map.put("size",sizeString); map.put("name",newFileName);//文件新名称 map.put("url",url); listMap.add(map); } //以json方式输出到页面 return listMap; }else{ return null; } }
<br>
前端
前端代码: 文件多选,实际上在
<input type="file" name="fileupmulti" accept="image/jpeg,image/png" onchange="mutiFiles(this)" multiple/>
多加了一个 multiple 属性
onchange 事件代码
// 单文件上传 function uploadFile(obj){ // 建立一个 FormData 对象,用一些键值对来模拟一系列表单控件 // 即把 form 中全部表单元素的 name 与 value 组装成一个 queryString let form = new FormData(); let fileObj = obj.files[0]; form.append('doc',fileObj); // ajax 代码... } // 多文件上传(多选) function mutiFiles(obj){ let form = new FormData(); let fileObj = obj.files; let length = fileObj.length; // 将 fileObj 转换成数组 // let filese = Array.from(fileObj); for(let i = 0; i < length; i++){ form.append('doc', fileObj[i]); } // ajax 代码... } // 多文件上传(单选:一个一个选择文件,最后点击提交按钮触发的方法) function multipartone(){ let file1 = $('.fileupon11').get(0).files[0]; let file2 = $('.fileupon12').get(0).files[0]; let file3 = $('.fileupon13').get(0).files[0]; //若是都是空,则直接退出 isEmpty(file1) && isEmpty(file2) && isEmpty(file3) return; let form = new FormData(); //用同一个名字,注入到controller层的参数数组 form.append('doc', file1); form.append('doc', file2); form.append('doc', file3); // ajax 代码... }
要想在当前界面显示上传的文件,而不跳转,就利用 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){ // TODO } })
<br>
controller 层调用
package com.krry.controller; import java.io.IOException; import java.util.HashMap; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.json.JSONException; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import com.krry.util.UploadUtil; /** * 文件上传类 * KrryUploadController * @author krry * @version 1.0.0 * */ @Controller @RequestMapping("/upload") public class KrryUploadController { /** * 单文件上传 * @param file * @param request * @return * @throws IllegalStateException * @throws IOException * @throws JSONException */ @ResponseBody @RequestMapping(value = "/file") public String krryupload(@RequestParam("doc") MultipartFile file, HttpServletRequest request) throws IllegalStateException, IOException, JSONException{ //调用工具类完成上传,返回相关数据到页面 return UploadUtil.simUpload(file, request); } /** * 多文件上传 * @param file * @param request * @return * @throws IllegalStateException * @throws IOException * @throws JSONException */ // 这里的MultipartFile[] file表示前端页面上传过来的多个文件,file对应页面中多个file类型的input标签的name,但框架只会将一个文件封装进一个MultipartFile对象, // 并不会将多个文件封装进一个MultipartFile[]数组,直接使用会报[Lorg.springframework.web.multipart.MultipartFile;.<init>()错误, // 因此须要用@RequestParam校订参数(参数名与MultipartFile对象名一致),固然也能够这么写:@RequestParam("file") MultipartFile[] files。 @ResponseBody @RequestMapping(value = "/mutl") public List<HashMap<String, Object>> krryuploadMutl(@RequestParam("doc") MultipartFile[] file, HttpServletRequest request) throws IllegalStateException, IOException, JSONException{ //调用工具类完成上传,返回相关数据到页面 return UploadUtil.mutlUpload(file, request); } }
<br>
进度条
要显示上传进度条,我这里采用原生 ajax 方法
function uploadFile(obj) { // ... // 一些获取上传对象的相关代码 // 建立一个 ajax 对象 var xhr = new XMLHttpRequest(); // 规定请求的类型、URL 以及是否异步处理请求。true为异步 // 请求是异步的。由于要实时获取到上传的进度,则请求需是异步的,若是是同步的话,会直到请求完成才能获取到响应 xhr.open("post", basePath+"/upload/file", true); // 上传成功进入的回调函数 xhr.onreadystatechange = function(){ if(xhr.readyState==4 && xhr.status==200){ // 状态 4 和 200 表明和服务器端交互成功 // 获取上传成功的返回数据 var data = xhr.responseText.trim(); jdata = eval("("+data+")"); krry_uploadsuccess(jdata); } }; // 监听文件上传的进度 xhr.upload.addEventListener("progress", progressFunction, false); // 发送http请求:将请求发送到服务器,与后台交互 xhr.send(form); } // 上传进度的回调函数 function progressFunction(event) { let prograssbarDom = document.getElementById("prograssbar"); let fileRea = document.getElementById("fileRea"); if (prograssbarDom && event.lengthComputable) { let percent = event.loaded / event.total; //文件上传进度百分比 let p = Math.floor(percent*100); prograssbarDom.style.width = p+"%"; fileRea.innerHTML = p+"%"; } }
<br>
附上优化文件大小的代码:
/** * 将文件的字节数转换成文件的大小 * com.krry.uitl * 方法名:format * @author krry * @param size * @return String * @exception * @since 1.0.0 */ public static String format(long size){ float fsize = size; String fileSizeString; if (fsize < 1024) { fileSizeString = String.format("%.2f", fsize) + "B"; //2f表示保留两位小数 } else if (fsize < 1048576) { fileSizeString = String.format("%.2f", fsize/1024) + "KB"; } else if (fsize < 1073741824) { fileSizeString = String.format("%.2f", fsize/1024/1024) + "MB"; } else if (fsize < 1024 * 1024 * 1024) { fileSizeString = String.format("%.2f", fsize/1024/1024/1024) + "GB"; } else { fileSizeString = "0B"; } return fileSizeString; }
博客地址:https://ainyi.com/76