需求:javascript
文件批量上傳,支持斷點續傳。html
文件批量下載,支持斷點續傳。java
使用JS可以實現批量下載,可以提供接口從指定url中下載文件並保存在本地指定路徑中。web
服務器不須要打包。ajax
支持大文件斷點下載。好比下載10G的文件。chrome
PC端全平臺支持。Windows,macOS,Linuxapache
全瀏覽器支持。ie6,ie7,ie8,ie9,ie10,ie11,edge,firefox,chrome,safarijson
這篇文章主要介紹了SpringMVC+Ajax實現文件批量上傳和下載功能實例代碼,代碼分爲上傳form和上傳ajax,具體實例代碼你們參考下本文後端
今天作了文件的上傳下載,小小總結一下,基本的web項目創建及SpringMVC框架搭建此處不詳細寫出來了。瀏覽器
上傳form:
<form id="uploadfiles" enctype="multipart/form-data">
<input type="file" multiple="multiple" id="file_upload" name="file_upload" />
<input type="button" value="上傳" onclick="upload()" />
</form>
上傳Ajax:
<script type="text/javascript">
/*
* 上傳文件
*/
function upload(){
var formData = new FormData($( "#uploadfiles" )[0]);
$.ajax({
type: "post",
url: "./path/upload",
dataType: "json",
data: formData,
/**
*必須false纔會自動加上正確的Content-Type
*/
contentType : false,
/**
* 必須false纔會避開jQuery對 formdata 的默認處理
* XMLHttpRequest會對 formdata 進行正確的處理
*/
processData : false,
success: function(data){//從後端返回數據進行處理
if(data){
alert("上傳成功!");
}else{
alert("上傳失敗!");
}
},
error: function(err) {//提交出錯
$("#msg").html(JSON.stringify(err));//打出響應信息
alert("服務器無響應");
}
});
}
</script>
上傳文件塊
<%@page language="java" import="up6.DBFile" pageEncoding="UTF-8"%>
<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="up6.FileBlockWriter" %>
<%@page import="up6.XDebug" %>
<%@page import="up6.*" %>
<%@page import="up6.biz.*" %>
<%@page import="org.apache.commons.fileupload.FileItem" %>
<%@page import="org.apache.commons.fileupload.FileItemFactory" %>
<%@page import="org.apache.commons.fileupload.FileUploadException" %>
<%@page import="org.apache.commons.fileupload.disk.DiskFileItemFactory" %>
<%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload" %>
<%@page import="org.apache.commons.lang.*" %>
<%@page import="java.net.URLDecoder"%>
<%@page import="java.util.Iterator"%>
<%@page import="net.sf.json.JSONObject"%>
<%@page import="java.util.List"%>
<% out.clear();
String uid = request.getHeader("uid");//
String id = request.getHeader("id");
String lenSvr = request.getHeader("lenSvr");
String lenLoc = request.getHeader("lenLoc");
String blockOffset = request.getHeader("blockOffset");
String blockSize = request.getHeader("blockSize");
String blockIndex = request.getHeader("blockIndex");
String blockMd5 = request.getHeader("blockMd5");
String complete = request.getHeader("complete");
String pathSvr = "";
//參數爲空
if( StringUtils.isBlank( uid )
|| StringUtils.isBlank( id )
|| StringUtils.isBlank( blockOffset ))
{
XDebug.Output("param is null");
return;
}
// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List files = null;
try
{
files = upload.parseRequest(request);
}
catch (FileUploadException e)
{// 解析文件數據錯誤
out.println("read file data error:" + e.toString());
return;
}
FileItem rangeFile = null;
// 獲得全部上傳的文件
Iterator fileItr = files.iterator();
// 循環處理全部文件
while (fileItr.hasNext())
{
// 獲得當前文件
rangeFile = (FileItem) fileItr.next();
if(StringUtils.equals( rangeFile.getFieldName(),"pathSvr"))
{
pathSvr = rangeFile.getString();
pathSvr = PathTool.url_decode(pathSvr);
}
}
boolean verify = false;
String msg = "";
String md5Svr = "";
long blockSizeSvr = rangeFile.getSize();
if(!StringUtils.isBlank(blockMd5))
{
md5Svr = Md5Tool.fileToMD5(rangeFile.getInputStream());
}
verify = Integer.parseInt(blockSize) == blockSizeSvr;
if(!verify)
{
msg = "block size error sizeSvr:" + blockSizeSvr + "sizeLoc:" + blockSize;
}
if(verify && !StringUtils.isBlank(blockMd5))
{
verify = md5Svr.equals(blockMd5);
if(!verify) msg = "block md5 error";
}
if(verify)
{
//保存文件塊數據
FileBlockWriter res = new FileBlockWriter();
//僅第一塊建立
if( Integer.parseInt(blockIndex)==1) res.CreateFile(pathSvr,Long.parseLong(lenLoc));
res.write( Long.parseLong(blockOffset),pathSvr,rangeFile);
up6_biz_event.file_post_block(id,Integer.parseInt(blockIndex));
JSONObject o = new JSONObject();
o.put("msg", "ok");
o.put("md5", md5Svr);
o.put("offset", blockOffset);//基於文件的塊偏移位置
msg = o.toString();
}
rangeFile.delete();
out.write(msg);
%>
下載的jsp頁面代碼根據需求不一樣本身設計,這裏給出jsp代碼:
<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="up6.*" %>
<%@page import="up6.model.*" %>
<%@page import="java.nio.*" %>
<%@page import="java.nio.channels.*" %>
<%@page import="java.net.URLDecoder" %>
<%@page import="java.net.URLEncoder" %>
<%@page import="org.apache.commons.lang.*" %>
<%@page import="com.google.gson.FieldNamingPolicy" %>
<%@page import="com.google.gson.Gson" %>
<%@page import="com.google.gson.GsonBuilder" %>
<%@page import="com.google.gson.annotations.SerializedName" %>
<%@page import="java.io.*" %>
<% out.clear();
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
String fid = request.getHeader("id");
String blockIndex = request.getHeader("blockIndex");//基於1
String blockOffset = request.getHeader("blockOffset");//塊偏移,相對於整個文件
String blockSize = request.getHeader("blockSize");//塊大小(當前須要下載的大小)
String pathSvr = request.getHeader("pathSvr");//文件在服務器的位置
pathSvr = PathTool.url_decode(pathSvr);
if ( StringUtils.isBlank(fid)
||StringUtils.isBlank(blockIndex)
||StringUtils.isEmpty(blockOffset)
||StringUtils.isBlank(blockSize)
||StringUtils.isBlank(pathSvr))
{
response.setStatus(500);
response.setHeader("err","參數爲空");
return;
}
File f = new File(pathSvr);
//文件不存在
if(!f.exists())
{
response.setStatus(500);
OutputStream os = response.getOutputStream();
System.out.println(String.format("%s 文件不存在",pathSvr));
os.close();
return;
}
long fileLen = f.length();
response.setContentType("application/x-download");
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.addHeader("Content-Length",blockSize);
response.setDateHeader("Expires", 0);
OutputStream os = response.getOutputStream();
try
{
RandomAccessFile raf = new RandomAccessFile(pathSvr,"r");
int readToLen = Integer.parseInt(blockSize);
int readLen = 0;
raf.seek( Long.parseLong(blockOffset) );//定位索引
byte[] data = newbyte[1048576];
while( readToLen > 0 )
{
readLen = raf.read(data,0,Math.min(1048576,readToLen) );
readToLen -= readLen;
os.write(data, 0, readLen);
}
os.flush();
os.close();
raf.close();
os = null;
response.flushBuffer();
out.clear();
out = pageContext.pushBody();
}
catch(Exception e)
{
response.setStatus(500);
os.close();
out.close();
e.printStackTrace();
}
finally
{
if(os != null)
{
os.close();
os = null;
}
out.clear();
out = pageContext.pushBody();
}%>
這裏咱們進行了優化,下載文件時將不在服務器打包。這個優化對於大型文件的下載來講大幅度提高了效率,並且節省了服務器的資源。當下載用戶比較多的時候,服務器將不會出現打包多個文件致使磁盤空間被佔滿的狀況。
下載頁面若是用Ajax提交請求的話要注意:ajax函數的返回類型只有xml、text、json、html等類型,沒有「流」類型,因此咱們要實現ajax下載,不可以使用相應的ajax函數進行文件下載。但能夠用js生成一個form,用這個form提交參數,並返回「流」類型的數據。
例子:
function download(){
var form=$("<form>");//定義一個form表單
form.attr("style","display:none");
form.attr("target","");
form.attr("method","post");
form.attr("action","./path/download");//請求url
var input1=$("<input>");
input1.attr("type","hidden");
input1.attr("name","rows");//設置屬性的名字
input1.attr("value",「test」);//設置屬性的值
$("body").append(form);//將表單放置在web中
form.append(input1);
form.submit();//表單提交
}
總結
以上所述是小編給你們介紹的SpringMVC+Ajax實現文件批量上傳和下載功能實例代碼,但願對你們有所幫助,若是你們有任何疑問請給我留言,小編會及時回覆你們的。
批量上傳效果:
批量下載效果