JavaWeb實(shí)現(xiàn)多文件上傳及zip打包下載
本文實(shí)例為大家分享了javaweb多文件上傳及zip打包下載的具體代碼,供大家參考,具體內(nèi)容如下
項(xiàng)目中經(jīng)常會(huì)使用到文件上傳及下載的功能。本篇文章總結(jié)場(chǎng)景在JavaWeb環(huán)境下,多文件上傳及批量打包下載功能,包括前臺(tái)及后臺(tái)部分。
首先明確一點(diǎn):
無(wú)法通過(guò)頁(yè)面的無(wú)刷新ajax請(qǐng)求,直接發(fā)下載、上傳請(qǐng)求。上傳和下載,均需要在整頁(yè)請(qǐng)求的基礎(chǔ)上實(shí)現(xiàn)。項(xiàng)目中一般通過(guò)構(gòu)建form表單形式實(shí)現(xiàn)這一功能。
一、多文件上傳
項(xiàng)目需求為實(shí)現(xiàn)多圖片上傳功能。參考測(cè)試了網(wǎng)上找到的眾多插件方法后,決定選用Jquery原始上傳方案。以下按步驟貼出具體代碼。
1、HTML部分(可省略使用js構(gòu)建)
<form id="uploadForm" method="post" enctype="multipart/form-data"> <input type="file" hidden name="fileImage" multiple/> <a href="javascript:void(0);" rel="external nofollow" rel="external nofollow" id="fileSubmit" onclick="uploadFileMulti()">上傳資料</a> </form>
有幾點(diǎn)說(shuō)明:
1. form中 enctype=”multipart/form-data”
2. 例中使用標(biāo)簽,構(gòu)建submit
2、JS部分
var formData = new FormData($("#uploadForm")[0]); formData.append("foldName", "datumList"); //設(shè)置父級(jí)文件夾名稱 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) { //清空框文件內(nèi)容 $("#fileImage").val(""); var obj = document.getElementById('fileImage'); obj.outerHTML = obj.outerHTML; refreshDatumList(); showSuccessToast(result.message); } else { showWarningToast(result.message); } }, error: function () { showErrorToast('請(qǐng)求失??!') } });
以上有幾點(diǎn)說(shuō)明:
1. var formData = new FormData($(“#uploadForm”)[0]);
2. 使用 formData.append(“oderCode”, selfOrderCode); 添加其他參數(shù)
Java后臺(tái)
MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request; List<MultipartFile> files = mRequest.getFiles("fileImage");
以上有幾點(diǎn)說(shuō)明:
1. 獲取MultipartHttpServletRequest,對(duì)應(yīng)file標(biāo)簽的name
二、文件批量下載
本項(xiàng)目中,需求為批量下載某一批次文件。使用zip在服務(wù)器壓縮文件,之后將文件下載到客戶機(jī)。
網(wǎng)上查詢,使用Java自帶的文件輸出類不能解決壓縮文件中文件名亂碼的問(wèn)題。解決方法:使用ant.jar包,創(chuàng)建壓縮文件時(shí),可以設(shè)置文件的編碼格式,文件名亂碼的問(wèn)題就解決了。
HTML部分(可省略使用js構(gòu)建)
<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);" rel="external nofollow" rel="external nofollow" 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();//表單提交 }
后臺(tái)部分
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"; //在服務(wù)器端創(chuàng)建打包下載的臨時(shí)文件 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); //設(shè)置壓縮文件內(nèi)的字符編碼,不然會(huì)變成亂碼 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; //流需要分開的數(shù)量 int leaveByte = 0; //文件剩下的字符數(shù) byte[] inOutbyte; //byte數(shù)組接受文件的數(shù)據(jù) streamTotal = bInStream.available(); //通過(guò)available方法取得流的最大字符數(shù) streamNum = (int) Math.floor(streamTotal / MAX_BYTE); //取得流文件需要分開的數(shù)量 leaveByte = (int) streamTotal % MAX_BYTE; //分開文件之后,剩余的數(shù)量 if (streamNum > 0) { for (int j = 0; j < streamNum; ++j) { inOutbyte = new byte[MAX_BYTE]; //讀入流,保存在byte數(shù)組 bInStream.read(inOutbyte, 0, MAX_BYTE); outputstream.write(inOutbyte, 0, MAX_BYTE); //寫出流 } } //寫出剩下的流數(shù)據(jù) 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(); //關(guān)閉 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(); //將生成的服務(wù)器端文件刪除 } catch (IOException ex) { ex.printStackTrace(); } }
以上基本滿足文件上傳下載所需。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于springBoot配置文件properties和yml中數(shù)組的寫法
這篇文章主要介紹了springBoot配置文件properties和yml中數(shù)組的寫法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11Java教程package和import訪問(wèn)控制的步驟詳解
這篇文章主要為大家介紹了Java教程package和import訪問(wèn)控制的步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06Java將Exception信息轉(zhuǎn)為String字符串的方法
今天小編就為大家分享一篇Java將Exception信息轉(zhuǎn)為String字符串的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10一個(gè)Java中BigDecimal的問(wèn)題記錄
這篇文章主要給大家介紹了關(guān)于Java中一個(gè)BigDecimal問(wèn)題的相關(guān)資料,通過(guò)文中介紹的方法可以很方便的解決BigDecimal進(jìn)行計(jì)算的時(shí)候不管怎么計(jì)算,最后得到的值都沒(méi)有變化的問(wèn)題,需要的朋友可以參考下2021-11-11Java靜態(tài)代理和動(dòng)態(tài)代理的深入講解
這篇文章主要給大家介紹了關(guān)于Java靜態(tài)代理和動(dòng)態(tài)代理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Java使用設(shè)計(jì)模式中迭代器模式構(gòu)建項(xiàng)目的代碼結(jié)構(gòu)示例
這篇文章主要介紹了Java使用設(shè)計(jì)模式中迭代器模式構(gòu)建項(xiàng)目的代碼結(jié)構(gòu)示例,迭代器模式能夠?qū)υL問(wèn)者隱藏對(duì)象的內(nèi)部細(xì)節(jié),需要的朋友可以參考下2016-05-05SpringMVC框架實(shí)現(xiàn)Handler處理器的三種寫法
這篇文章主要介紹了SpringMVC框架實(shí)現(xiàn)Handler處理器的三種寫法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02