一.先说说上传
第一步:
pom.xml文件 加上 上传文件依赖架包
1 <dependency> 2 <groupId>commons-fileupload</groupId> 3 <artifactId>commons-fileupload</artifactId> 4 <version>1.3.1</version> 5 </dependency>
并且在配置文件中配置:
1 <!-- 实现文件上传,这样一旦某个Request是一个MultipartRequest,它就会首先被MultipartResolver处理,然后再转发相应的Controller --> 2 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 3 <!-- 设置上传文件的最大尺寸为1GB --> 4 <property name="maxUploadSize"> 5 <value>1073741824</value> 6 </property> 7 </bean>
第二步:
页面添加 上传需要的input框和按钮
upload.jsp代码:
1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 2 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 4 5 <% 6 String path = request.getContextPath(); 7 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 8 %> 9 <!DOCTYPE HTML> 10 <html> 11 <head> 12 <meta charset="utf-8"> 13 <meta name="renderer" content="webkit|ie-comp|ie-stand"> 14 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 15 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,member-scalable=no" /> 16 <meta http-equiv="Cache-Control" content="no-siteapp" /> 17 <link rel="stylesheet" href="../bootstrap/css/bootstrap.min.css"/> 18 <link rel="stylesheet" href="../upload/css/default.css" /> 19 <link media="all" rel="stylesheet" href="../upload/css/fileinput.css"/> 20 <title>上传位点信息</title> 21 </head> 22 <body> 23 <div class="pd-20"> 24 <form enctype="multipart/form-data" method="post"> 25 <div class="form-group"> 26 <input id="file-4" type="file" class="file" data-upload-url="#"> 27 </div> 28 <hr> 29 <div class="form-group col-lg-3" style="margin-left:30%;padding-left:5%;"> 30 <button class="btn btn-info" type="reset">刷新</button> 31 <button class="btn btn-primary upFileButton" type="button">上传</button> 32 <button class="btn btn-default" type="reset">重置</button> 33 </div> 34 </form> 35 </div> 36 37 <script type="text/javascript" src="../lib/jquery/1.9.1/jquery.min.js"></script> 38 <script type="text/javascript" src="../lib/layer/1.9.3/layer.js"></script> 39 <script type="text/javascript" src="../bootstrap/js/bootstrap.min.js"></script> 40 <script type="text/javascript" src="../upload/js/fileinput.js"></script> 41 <script type="text/javascript" src="../js/geneinfo/disease/upload.js"></script> 42 </body> 43 </html>
input上传框如果想要好看一点的样子或者拖拽功能,可以使用页面上引用的CSS【upload/css/default.css和upload/css/fileinput.css】和JS【/upload/js/fileinput.js】这是引用别人现成的插件,可以网上找更好的资源来用。
upload.js代码:上传按钮的绑定事件
1 $(document).ready(function(){ 2 3 /** 4 * 上传按钮 5 */ 6 $(".upFileButton").click(function(){ 7 8 var file = $("#file-4").val(); 9 if(file == ""){ 10 layer.msg('选择上传文件后进行操作!', { 11 icon: 4, 12 time: 2000 13 }, function(){ 14 }); 15 }else{ 16 var fd = new FormData(); 17 fd.append("upfile", $("#file-4").get(0).files[0]); 18 $.ajax({ 19 url: "uploadFile.htmls?diseaseName="+parent.diseaseName+"&diseaseId="+parent.diseaseId1, 20 type: "POST", 21 processData: false, 22 contentType: false, 23 data: fd, 24 success: function(data) { 25 if(data == "基因位点信息上传成功!"){ 26 layer.msg(data, { 27 icon: 1, 28 time: 2000 29 }, function(){ 30 }); 31 parent.layer.close(parent.upload); 32 }else{ 33 layer.msg(data, { 34 icon: 4, 35 time: 2000 36 }, function(){ 37 }); 38 } 39 40 } 41 }); 42 } 43 return ; 44 }); 45 });
核心部分就是:
var fd = new FormData();
fd.append("upfile", $("#file-4").get(0).files[0]);
第三步:
在服务器上处理接收过来的file文件:以输入流的形式读取到服务器端,再以输出流将temp临时文件写到服务器的磁盘上,就完成上传功能。
Controller核心部分:
【核心类 MultipartFile】
1 @RequestMapping("/uploadFile") 2 @ResponseBody 3 public String uploadFile(@RequestParam("upfile")MultipartFile partFile,HttpServletRequest request,String diseaseName,String diseaseId) throws IOException, EncryptedDocumentException, InvalidFormatException{//MultipartFile这里得到了上传的文件 4 5 // 得到上传服务器的路径 6 String path = "d:/file-ave/"; 7 // 得到上传的文件的文件名 8 String filename = partFile.getOriginalFilename(); 9 InputStream inputStream = partFile.getInputStream(); 10 byte[] b = new byte[1073741824]; 11 int length = inputStream.read(b); 12 path += filename; 13 // 文件流写到服务器端 14 FileOutputStream outputStream = new FileOutputStream(path); 15 outputStream.write(b, 0, length); 16 inputStream.close(); 17 outputStream.close(); 18 19 20 return ""; 21 }
备注:
以上完成上传,在配置文件和controller中都限定了允许上传的最大文件为1G.我们可以去掉文件大小的限制,大文件也可以进行上传!
可以配置文件中将大小限制去掉:
1 <!-- 实现文件上传,这样一旦某个Request是一个MultipartRequest,它就会首先被MultipartResolver处理,然后再转发相应的Controller --> 2 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 3 <!-- 设置上传文件的最大尺寸为1GB --> 4 <!-- <property name="maxUploadSize"> 5 <value>1073741824</value> 6 </property> --> 7 </bean>
JDK1.7提供使用NIO进行读写操作,Controller中可以修改为:
即下面的方法二
1 String path = "d:/file-ave/"+productName+"/"+diseaseName+"/"; 2 // 得到上传的文件的文件名 3 String filename = partFile.getOriginalFilename(); 4 InputStream inputStream = partFile.getInputStream(); 5 6 DecimalFormat df = new DecimalFormat(); 7 String fileSize = partFile.getSize()/1024>100 ? (partFile.getSize()/1024/1024>100? df.format(partFile.getSize()/1024/1024/1024)+"GB" :df.format(partFile.getSize()/1024/1024)+"MB" ) :df.format(partFile.getSize()/1024)+"KB"; 8 9 10 11 //方法1:配置文件中有配置最大文件大小 12 /*byte[] b = new byte[1073741824]; 13 int length = inputStream.read(b); 14 path += filename; 15 // 文件流写到服务器端 16 FileOutputStream outputStream = new FileOutputStream(path); 17 outputStream.write(b, 0, length); 18 inputStream.close(); 19 outputStream.close();*/ 20 //方法2: 21 path += filename; 22 long start = System.currentTimeMillis(); 23 Files.copy(inputStream, Paths.get(path)); 24 System.out.println(((double)System.currentTimeMillis()-start)/1000); 25 inputStream.close();
仅Files.copy(inputStream, Paths.get(path));就可以实现文件拷贝。不需要自己创建数组的大小,效率极高。
二.来看看下载
在页面提供一个超链接即可:
1 <td><a href='fileDownload.htmls?fileId="+item.fileId 2 +"' class='check'>【下载】</a>
Controller
1 @RequestMapping("/fileDownload") 2 public void fileDownload(String fileId,HttpServletResponse response) throws IOException, InterruptedException{ 3 // 4 5 Filelist filelist = filelistService.get(fileId); 6 Assert.notNull(filelist); 7 String filePath = filelist.getFilePath(); 8 String fileName = filelist.getFileName(); 9 String targetPath = "D:/biologyInfo/Download/"; 10 File file = new File(targetPath); 11 while(!file.exists()){ 12 file.mkdirs(); 13 } 14 FileInputStream inputStream = new FileInputStream(new File(filePath)); 15 /*File file2 = new File(targetPath+fileName); 16 if(!file2.exists()){ 17 18 }*/ 19 response.setContentType("multipart/form-data"); 20 response.setHeader("Content-Type", "application/octet-stream;charset=utf-8"); 21 response.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName, "utf-8"));//保证下载文件名不会出现乱码 22 OutputStream outputStream = response.getOutputStream(); 23 //这样下载下来的文件打不开是损坏的 24 /*while(inputStream.read() != -1){ 25 outputStream.write(inputStream.read()); 26 }*/ 27 28 byte[] b = new byte[1024]; 29 int length = 0; 30 while ((length = inputStream.read(b)) != -1) { 31 outputStream.write(b, 0, length); 32 } 33 inputStream.close(); 34 outputStream.close(); 35 }
在服务器端处理的时候,会碰上这样几个问题:
1.服务器提供下载功能,是要将文件下载到客户端的机子上,因此:OutputStream outputStream = response.getOutputStream();
2.如果是要下载服务器端的文件到服务器端的另一个地方,也就是写入再写出,那么需要OutputStream outputStream2 = new FileOutputStream(new File(目标文件夹+文件名)),否则会提示无法 磁盘无法访问,这个问题不关乎文件权限或者目标文件夹的权限。
三.上传的简单版本【不使用表单提交方式----上传按钮的简单上传】--使用H-ui前台框架
1.JSP页面
1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 2 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 4 5 <% 6 String path = request.getContextPath(); 7 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 8 %> 9 10 <!DOCTYPE HTML> 11 <html> 12 <head> 13 <meta charset="utf-8"> 14 <meta name="renderer" content="webkit|ie-comp|ie-stand"> 15 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 16 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=0.6,maximum-scale=1.0,user-scalable=no" /> 17 <meta http-equiv="Cache-Control" content="no-siteapp" /> 18 19 <link rel="stylesheet" type="text/css" href="../static/h-ui/css/H-ui.css" /> 20 <link rel="stylesheet" type="text/css" href="../lib/Hui-iconfont/1.0.7/iconfont.css" /> 21 <link rel="stylesheet" type="text/css" href="../lib/icheck/icheck.css" /> 22 <link rel="stylesheet" type="text/css" href="../static/h-ui/css/style.css" /> 23 <link rel="stylesheet" type="text/css" href="../css/welcome/welcome.css" /> 24 <link rel="stylesheet" type="text/css" href="../css/material/showAllMaterial.css" /> 25 26 <title>素材界面</title> 27 </head> 28 <body> 29 <div class="panel panel-secondary f-l" style="width: 99%"> 30 <div class="panel-header"> 31 <div class="f-l" style=" margin-top: 5px;"> 32 <!--不使用表单提交的方式--- 简单的按钮上传功能 --> 33 <span class="btn-upload"> 34 <a href="javascript:void();" class="btn btn-default radius"><i class="Hui-iconfont"></i> 上传素材</a> 35 <input id="upload_1" type="file" multiple name="file_0" class="input-file" accept="audio/*,video/*,image/*,application/*,text/*"> 36 </span> 37 38 </div> 39 40 </div> 41 <div class="panel-body"> 42 43 </div> 44 </div> 45 46 <script type="text/javascript" src="../lib/jquery/1.9.1/jquery.min.js"></script> 47 <script type="text/javascript" src="../lib/layer/2.1/layer.js"></script> 48 <script type="text/javascript" src="../lib/My97DatePicker/WdatePicker.js"></script> 49 <script type="text/javascript" src="../static/h-ui/js/H-ui.js"></script> 50 <script type="text/javascript" src="../js/material/showAllMaterial.js"></script> 51 52 </body> 53 </html>
JS文件 showAllMaterial.js
1 $(document).ready(function(){ 2 3 /* 简单的上传功能*/ 4 $("input[type='file']").change( function() { 5 var files = $("#upload_1")[0].files; 6 for (var i = 0; i < files.length; i++) { 7 var fileName = files[i].name; 8 //获取 后缀名 9 var suffix = fileName.substring(fileName.lastIndexOf('.')); 10 11 var fileDate = new FormData(); 12 fileDate.append("upfile",files[i]); 13 14 15 $.ajax({ 16 url: "upLoadMaterial.htmls", 17 type: "POST", 18 processData: false, 19 contentType: false, 20 data: fileDate, 21 success: function(data) { 22 //回调函数 23 alert("上传成功"); 24 } 25 }); 26 } 27 }); 28 });
2.Controller Java1.8
1 2 /* 简单的上传功能*/ 3 @RequestMapping("upLoadMaterial") 4 public void upLoadMaterial(@RequestParam("upfile")MultipartFile partFile,HttpServletRequest request) throws WxErrorException, IOException{ 5 6 System.out.println("上传永久素材"); 7 // String madiaId = null; 8 // String url = null; 9 // String materName = null; 10 File files = new File("d:/material/"); 11 if(!(files.exists())){ 12 files.mkdirs(); 13 } 14 File file = new File(files.getPath()+"/"+partFile.getOriginalFilename());//上传到服务器端的路径 15 InputStream is = partFile.getInputStream(); 16 FileUtils.copyToFile(is, file); 17 System.out.println(partFile.getContentType()); 18 System.out.println(file.getPath()); 19 20 // PermanentMaterialManager permanentMaterialManager = new PermanentMaterialManager(); 21 // permanentMaterialManager.otherMaterial(materName,file,madiaId,url); 22 23 } 24
未配置其他的东西 ,最简单的上传功能
四.上传的完善版本【表单提交方式,XMLHttpRequest在JS中处理,展现上传速度,进度条,消耗时间等】----使用bootstrap进行美化----org.springframework.web.multipart.MultipartFile后台接收
1.A.jsp页面上 有个按钮,可以打开上传页面
1 <span class="btn-upload"> 2 <a href="javascript:void();" class="btn btn-default radius uploadButton"><i class="Hui-iconfont"></i> 上传素材</a> 3 </span>
A.js文件 给这个按钮绑定 打开页面的功能---使用layer弹出页面,因此需要在JSP中引用layer架包
1 $(".uploadButton").click(function(){ 2 uploadView = layer.open({ 3 type: 2, 4 skin: 'layui-layer-lan', //加上边框 5 area: ['420px', '300px'], //宽高 6 content: "openUpLoadView.htmls" 7 }); 8 });
2.页面跳转通过后台的controller中的方法
1 //打开上传页面 2 @RequestMapping("openUpLoadView") 3 public String openUpLoadView(){ 4 return "/material/upload"; 5 }
3.upload.jsp页面 也就是上传文件的页面
1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 2 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 4 5 <% 6 String path = request.getContextPath(); 7 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 8 %> 9 <!DOCTYPE html> 10 <html> 11 <head> 12 <link rel="stylesheet" type="text/css" href="../bootstrap/css/bootstrap.css" /> 13 <link rel="stylesheet" type="text/css" href="../bootstrap/css/bootstrap-theme.css" /> 14 <title>使用XMLHttpRequest上传文件</title> 15 </head> 16 <body style="background-image: url('../images/bg123.png');"> 17 <form id="form1" enctype="multipart/form-data" method="post" > 18 <div class=""> 19 <label for="fileToUpload">Select a File to Upload</label> 20 <input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected()" class="btn btn-danger"/> 21 </div> 22 <div id="fileName"></div> 23 <div id="fileSize"></div> 24 <div id="fileType"></div> 25 <div class=""> 26 <input type="button" class="btn btn-success btn-sm" style="width: 20%;" onclick="uploadFile()" value="上传" /> 27 </div> 28 <div id="progressNumber"></div> 29 <div class="pro"></div> 30 <div class="progress"> 31 <div class="progress-bar progress-bar-warning progress-bar-striped active" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 0%;min-width: 5px;"> 32 33 </div> 34 </div> 35 </form> 36 <script type="text/javascript" src="../lib/jquery/1.9.1/jquery.min.js"></script> 37 <script type="text/javascript" src="../js/material/upload.js"></script> 38 <script type="text/javascript" src="../bootstrap/js/bootstrap.min.js"></script> 39 </body> 40 </html>
4.upload.js文件 处理上传文件,上传进度等
1 var startTime ;//开始上传时间 2 3 function fileSelected() { 4 var file = document.getElementById('fileToUpload').files[0]; 5 if (file) { 6 var fileSize = 0; 7 if (file.size > 1024 * 1024){ 8 if(file.size >1024 * 1024 * 1024) 9 fileSize = (Math.round(file.size * 100 / (1024 * 1024 * 1024)) / 100).toString() + 'GB'; 10 else 11 fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB'; 12 } 13 else{ 14 fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB'; 15 } 16 document.getElementById('fileName').innerHTML = '上传文件: ' + file.name; 17 document.getElementById('fileSize').innerHTML = '文件大小: ' + fileSize; 18 document.getElementById('fileType').innerHTML = '文件类型: ' + ((file.type == "")?"未识别类型":file.type); 19 } 20 } 21 22 function uploadFile() { 23 var fd = new FormData();//获取上传文件 24 fd.append("upfile", document.getElementById('fileToUpload').files[0]); 25 startTime = new Date();//获取起始时间,也就是开始上传的时间 26 var xhr = new XMLHttpRequest(); 27 xhr.upload.addEventListener("progress", uploadProgress, false); 28 xhr.addEventListener("load", uploadComplete, false); 29 xhr.addEventListener("error", uploadFailed, false); 30 xhr.addEventListener("abort", uploadCanceled, false); 31 xhr.open("POST", "uploadMaterial.htmls"); 32 xhr.send(fd); 33 } 34 35 function uploadProgress(evt) { 36 if (evt.lengthComputable) { 37 //evt.loaded 当前上传文件的大小 38 var percentComplete = Math.round(evt.loaded * 100 / evt.total); 39 document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%'; 40 var currtTime = new Date();//当前时间 41 var costTime = (currtTime - startTime)/1000+1;//消耗的时间 42 var speed = evt.loaded/((currtTime - startTime)/1000)/1024;//上传速度 KB/S 43 var sp = evt.loaded/((currtTime - startTime)/1000);//用于计算上传速度的变量 44 var speed = sp/1024>1 ? 45 (sp/1024/1024>1 ? 46 (sp/1024/1024/1024>1 ? 47 (sp/1024/1024/1024).toFixed(2)+" GB/秒" 48 :(sp/1024/1024).toFixed(2)+" MB/秒") 49 :(sp/1024).toFixed(2)+" KB/秒" ) 50 :sp.toFixed(2)+" B/秒";//文件上传速度 toFixed(2)截取保留小数点后2位,作用对象是number类型的 51 var loaded = evt.loaded/1024>1 ? 52 (evt.loaded/1024/1024>1 ? 53 (evt.loaded/1024/1024/1024>1 ? 54 (evt.loaded/1024/1024/1024).toFixed(2)+" GB" 55 :(evt.loaded/1024/1024).toFixed(2)+" MB") 56 :(evt.loaded/1024).toFixed(2)+" KB" ) 57 :evt.loaded.toFixed(2)+" B";//文件已上传大小 58 $(".pro").html("上传大小:"+loaded +"消耗时间:"+costTime.toFixed(3)+"s 上传速度:"+speed+"KB/S"); 59 $("div[role='progressbar']").width(percentComplete+"%"); 60 $("div[role='progressbar']").html(percentComplete+"%"); 61 62 } 63 else { 64 document.getElementById('progressNumber').innerHTML = 'unable to compute'; 65 } 66 } 67 68 function uploadComplete(evt) {//成功的回调函数 69 /* This event is raised when the server send back a response */ 70 alert(evt.target.responseText); 71 } 72 73 function uploadFailed(evt) {//失败的回调函数 74 alert("There was an error attempting to upload the file."); 75 } 76 77 function uploadCanceled(evt) {//用户或者浏览器关闭连接导致上传中断的上传 78 alert("The upload has been canceled by the user or the browser dropped the connection."); 79 } 80 $(document).ready(function(){ 81 82 });
5.上传给服务器 controller处理方法--仅将上传文件保存,并返回一串字符串而已
1 import org.apache.commons.io.FileUtils; 2 3 //开始上传 4 @RequestMapping("uploadMaterial") 5 @ResponseBody 6 public String uploadMaterial(@RequestParam("upfile")MultipartFile partFile,HttpServletRequest request) throws IOException{ 7 File files = new File("d:/material/"); 8 if(!(files.exists())){ 9 files.mkdirs(); 10 } 11 File file = new File(files.getPath()+"/"+partFile.getOriginalFilename());//上传到服务器端的路径 12 InputStream is = partFile.getInputStream(); 13 FileUtils.copyInputStreamToFile(is, file); 14 System.out.println(partFile.getContentType()); 15 System.out.println(file.getPath()); 16 return "/material/upload"; 17 }
效果图: