JavaWeb多檔案上傳及zip打包下載
阿新 • • 發佈:2019-02-03
專案中經常會使用到檔案上傳及下載的功能。本篇文章總結場景在JavaWeb環境下,多檔案上傳及批量打包下載功能,包括前臺及後臺部分。
首先明確一點:
無法通過頁面的無重新整理ajax請求,直接發下載、上傳請求。上傳和下載,均需要在整頁請求的基礎上實現。專案中一般通過構建form表單形式實現這一功能。
一、多檔案上傳
專案需求為實現多圖片上傳功能。參考測試了網上找到的眾多外掛方法後,決定選用Jquery原始上傳方案。以下按步驟貼出具體程式碼。
1、HTML部分(可省略使用js構建)
<form id="uploadForm" method="post" enctype="multipart/form-data"> <input type="file" hidden name="fileImage" multiple/> <a href="javascript:void(0);" id="fileSubmit" onclick="uploadFileMulti()">上傳資料</a> </form>
有幾點說明:
1. form中 enctype=”multipart/form-data”
2. 例中使用標籤,構建submit
2、JS部分
var formData = new FormData($("#uploadForm")[0]); formData.append("foldName", "datumList"); //設定父級資料夾名稱 formData.append("oderCode", selfOrderCode); formData.append("datumType", datumType); $.ajax({ type: "POST", data: formData, url: "order/datumList/batchInsertDatumLists", contentType: false, processData: false, success: function (result) { if (result.success) { //清空框檔案內容 $("#fileImage").val(""); var obj = document.getElementById('fileImage'); obj.outerHTML = obj.outerHTML; refreshDatumList(); showSuccessToast(result.message); } else { showWarningToast(result.message); } }, error: function () { showErrorToast('請求失敗!') } });
以上有幾點說明:
1. var formData = new FormData($(“#uploadForm”)[0]);
2. 使用 formData.append(“oderCode”, selfOrderCode); 新增其他引數
Java後臺
MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
List<MultipartFile> files = mRequest.getFiles("fileImage");
以上有幾點說明:
1. 獲取MultipartHttpServletRequest,對應file標籤的name
二、檔案批量下載
本專案中,需求為批量下載某一批次檔案。使用zip在伺服器壓縮檔案,之後將檔案下載到客戶機。
網上查詢,使用Java自帶的檔案輸出類不能解決壓縮檔案中檔名亂碼的問題。解決方法:使用ant.jar包,建立壓縮檔案時,可以設定檔案的編碼格式,檔名亂碼的問題就解決了。
HTML部分(可省略使用js構建)
<form id="uploadForm" method="post" enctype="multipart/form-data">
<div class="product-dl">
<input type="hidden" name="orderCode"/>
<input type="hidden" name="datumType"/>
<a href="javascript:void(0);" class="btn" onclick="batchDatumListDownLoad()">批量下載</a>
</div>
</form>
JS部分
//批量下載
function batchDatumListDownLoad() {
var param = {};
param.datumType = $("#datumTypeQ").val();
if (param.datumType == -1) {
param.datumType = null; //查詢所有
}
param.orderCode = selfOrderCode;
$("#uploadForm input[name=orderCode]").val(param.orderCode);
$("#uploadForm input[name=datumType]").val(param.datumType);
var form = $("#uploadForm")[0];
form.action = "order/datumList/batchDownLoadDatumList";
form.method = "post";
form.submit();//表單提交
}
後臺部分
public void batchDownLoadDatumList(DatumListVo datumListVo, HttpServletResponse response) {
try {
//查詢檔案列表
List<DatumListVo> voList = datumListService.queryDatumLists(datumListVo);
//壓縮檔案
List<File> files = new ArrayList<>();
for (DatumListVo vo : voList) {
File file = new File(vo.getDatumUrl());
files.add(file);
}
String fileName = datumListVo.getOrderCode() + "_" + datumListVo.getDatumType() + ".zip";
//在伺服器端建立打包下載的臨時檔案
String globalUploadPath = "";
String osName = System.getProperty("os.name");
if (osName.toLowerCase().indexOf("windows") >= 0) {
globalUploadPath = GlobalKeys.getString(GlobalKeys.WINDOWS_UPLOAD_PATH);
} else if (osName.toLowerCase().indexOf("linux") >= 0 || osName.toLowerCase().indexOf("mac") >= 0) {
globalUploadPath = GlobalKeys.getString(GlobalKeys.LINUX_UPLOAD_PATH);
}
String outFilePath = globalUploadPath + File.separator + fileName;
File file = new File(outFilePath);
//檔案輸出流
FileOutputStream outStream = new FileOutputStream(file);
//壓縮流
ZipOutputStream toClient = new ZipOutputStream(outStream);
//設定壓縮檔案內的字元編碼,不然會變成亂碼
toClient.setEncoding("GBK");
ZipUtil.zipFile(files, toClient);
toClient.close();
outStream.close();
ZipUtil.downloadZip(file, response);
} catch (Exception e) {
e.printStackTrace();
}
}
其中ZipUtil.java
/**
* 壓縮檔案列表中的檔案
*
* @param files
* @param outputStream
* @throws IOException
*/
public static void zipFile(List files, ZipOutputStream outputStream) throws IOException, ServletException {
try {
int size = files.size();
//壓縮列表中的檔案
for (int i = 0; i < size; i++) {
File file = (File) files.get(i);
try {
zipFile(file, outputStream);
} catch (Exception e) {
continue;
}
}
} catch (Exception e) {
throw e;
}
}
/**
* 將檔案寫入到zip檔案中
*
* @param inputFile
* @param outputstream
* @throws Exception
*/
public static void zipFile(File inputFile, ZipOutputStream outputstream) throws IOException, ServletException {
try {
if (inputFile.exists()) {
if (inputFile.isFile()) {
FileInputStream inStream = new FileInputStream(inputFile);
BufferedInputStream bInStream = new BufferedInputStream(inStream);
ZipEntry entry = new ZipEntry(inputFile.getName());
outputstream.putNextEntry(entry);
final int MAX_BYTE = 10 * 1024 * 1024; //最大的流為10M
long streamTotal = 0; //接受流的容量
int streamNum = 0; //流需要分開的數量
int leaveByte = 0; //檔案剩下的字元數
byte[] inOutbyte; //byte陣列接受檔案的資料
streamTotal = bInStream.available(); //通過available方法取得流的最大字元數
streamNum = (int) Math.floor(streamTotal / MAX_BYTE); //取得流檔案需要分開的數量
leaveByte = (int) streamTotal % MAX_BYTE; //分開檔案之後,剩餘的數量
if (streamNum > 0) {
for (int j = 0; j < streamNum; ++j) {
inOutbyte = new byte[MAX_BYTE];
//讀入流,儲存在byte陣列
bInStream.read(inOutbyte, 0, MAX_BYTE);
outputstream.write(inOutbyte, 0, MAX_BYTE); //寫出流
}
}
//寫出剩下的流資料
inOutbyte = new byte[leaveByte];
bInStream.read(inOutbyte, 0, leaveByte);
outputstream.write(inOutbyte);
outputstream.closeEntry(); //Closes the current ZIP entry and positions the stream for writing the next entry
bInStream.close(); //關閉
inStream.close();
}
} else {
throw new ServletException("檔案不存在!");
}
} catch (IOException e) {
throw e;
}
}
/**
* 下載打包的檔案
*
* @param file
* @param response
*/
public static void downloadZip(File file, HttpServletResponse response) {
try {
// 以流的形式下載檔案。
BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
toClient.write(buffer);
toClient.flush();
toClient.close();
file.delete(); //將生成的伺服器端檔案刪除
} catch (IOException ex) {
ex.printStackTrace();
}
}
以上基本滿足檔案上傳下載所需