老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業提供網站建設、域名注冊、服務器等服務

java多文件壓縮下載的解決方法

Java多文件壓縮下載解決方案,供大家參考,具體內容如下

成都創新互聯成都網站建設按需定制網站,是成都網站設計公司,為成都集裝箱提供網站建設服務,有成熟的網站定制合作流程,提供網站定制設計服務:原型圖制作、網站創意設計、前端HTML5制作、后臺程序開發等。成都網站制作熱線:13518219792

需求:

會員運營平臺經過改版后頁面增加了許多全部下載鏈接,上周上線比較倉促,全部下載是一個直接下載ZIP壓縮文件的鏈接,每個ZIP壓縮文件都是由公司運營人員將頁面需要下載的文件全部壓縮成一個ZIP壓縮文件,然后通過公司的交易運營平臺上傳至文件資料系統,會員運營平臺則可以直接獲取ZIP壓縮文件地址進行下載

下面是一個頁面示例:

java多文件壓縮下載的解決方法

需求分析:

通過上面需求和頁面可以分析出,公司運營人員將頁面全部需要下載的文件進行ZIP壓縮后上傳文件資料系統確實是一個緊急的解決方案,但是考慮到后面需求變更,頁面需要下載的文件也會跟著變更,每次變更需求,公司運營人員都需要重新進行壓縮文件,程序也需要進行相應的修改,這樣對于程序的維護性不友好,站在使用系統的客戶角度,每次都需要重新上傳,因此臨時解決方案不再符合軟件的良好擴展性和操作方便,因此才有了對頁面需要全部下載的文件使用程序壓縮處理并下載。

解決思路:

第一步:前端傳遞Ids字符串

由于會員運營系統顯示需要下載的文件是資料系統中的每條文件記錄的Id,因此前端頁面只需要將需要下載的所有文件Ids字符串(比如:'12,13,14')傳遞到后臺即可.

第二步:后臺處理

首先獲取到前端傳遞的ids字符串,將其轉換為Integer[]的ids數組,然后調用文件資料微服務根據id列表查詢對應的文件記錄(包含文件類型和文件地址路徑等信息),獲取到所有需要下載的文件路徑后壓縮成ZIP格式的文件進行下載。

具體實現壓縮下載方案:

第一種:先壓縮成ZIP格式文件,再下載

第二種:邊壓縮ZIP格式文件邊下載(直接輸出ZIP流)

前端具體實現代碼:

由于全部下載是一個a鏈接標簽,于是使用Ajax異步下載,后來功能實現后點擊下載一點反應都沒有,一度懷疑是后臺出錯,但是后臺始終沒有報錯,在網上看了一下Ajax異步不能下載文件(也就是Ajax不支持流類型數據),具體原因可以百度這篇博客,給到的解釋是:

原因

ajax的返回值類型是json,text,html,xml類型,或者可以說ajax的接收類型只能是string字符串,不是流類型,所以無法實現文件下載。但用ajax仍然可以獲得文件的內容,該文件將被保留在內存中,無法將文件保存到磁盤。這是因為JavaScript無法和磁盤進行交互,否則這會是一個嚴重的安全問題,js無法調用到瀏覽器的下載處理機制和程序,會被瀏覽器阻塞。

解釋的還算是比較好的。后面會寫一篇=文章詳細分析Ajax異步下載解決方案。

接下來考慮使用form表單標簽實現,最終配合使用input標簽實現了前端傳遞ids列表的問題,點擊a鏈接標簽觸發提交form標簽即可。

java多文件壓縮下載的解決方法

在每一個需要下載的文件增加一個隱藏的input標簽,value值是這個文件的id值

java多文件壓縮下載的解決方法

具體點擊a鏈接標簽提交表單的JS代碼:

java多文件壓縮下載的解決方法

后端具體實現代碼:

第一種方案實現:

java多文件壓縮下載的解決方法

第二種方案實現:

java多文件壓縮下載的解決方法

附上完整代碼:

壓縮下載Controller

package com.huajin.jgoms.controller.user;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
 
import javax.servlet.http.HttpServletResponse;
 
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
import com.huajin.baymax.logger.XMsgError;
import com.huajin.baymax.logger.Xlogger;
import com.huajin.common.util.UUIDUtil;
import com.huajin.exchange.domain.sys.FeFileCenter;
import com.huajin.exchange.enums.sys.SysParamKey;
import com.huajin.exchange.po.sys.SysParamPo;
import com.huajin.jgoms.controller.HjBaseController;
import com.huajin.jgoms.service.FeFileCenterService;
import com.huajin.jgoms.service.SysParamService;
import com.huajin.jgoms.util.CompressDownloadUtil;
 
/**
 * 壓縮下載文件
 *
 * @author hongwei.lian
 * @date 2018年9月6日 下午6:29:05
 */
@Controller
@RequestMapping("/compressdownload")
public class CompressDownloadController extends HjBaseController {
 
 @Autowired
 private FeFileCenterService feFileCenterService;
 
 @Autowired
 private SysParamService sysParamService;
 
 /**
 * 多文件壓縮下載
 * 
 * @author hongwei.lian
 * @date 2018年9月6日 下午6:28:56
 */
 @RequestMapping("/downloadallfiles")
 public void downloadallfiles() {
 //-- 1、根據ids查詢下載的文件地址列表
 String ids = request().getParameter("ids");
 if (StringUtils.isEmpty(ids)) {
 return ;
 }
 //-- 將字符串數組改變為整型數組
 Integer[] idsInteger = CompressDownloadUtil.toIntegerArray(ids);
 List fileCenters = feFileCenterService.getFeFileByIds(super.getExchangeId(), idsInteger);
 if (CollectionUtils.isNotEmpty(fileCenters) && ObjectUtils.notEqual(idsInteger.length, fileCenters.size())) {
 //-- 要下載文件Id數組個數和返回的文件地址個數不一致
 return ;
 }
 
 //-- 2、轉換成文件列表
 List files = this.toFileList(fileCenters);
 //-- 檢查需要下載多文件列表中文件路徑是否都存在
 for (File file : files) {
 if (!file.exists()) {
 //-- 需要下載的文件中存在不存在地址
 return ;
 }
 }
 
 //-- 3、響應頭的設置
 String downloadName = UUIDUtil.getUUID() + ".zip";
 HttpServletResponse response = CompressDownloadUtil.setDownloadResponse(super.response(), downloadName);
 
 //-- 4、第一種方案:
 //-- 指定ZIP壓縮包路徑
// String zipFilePath = this.setZipFilePath(downloadName);
// try {
// //-- 將多個文件壓縮到指定路徑下
// CompressDownloadUtil.compressZip(files, new FileOutputStream(zipFilePath));
// //-- 下載壓縮包
// CompressDownloadUtil.downloadFile(response.getOutputStream(), zipFilePath);
// //-- 刪除臨時生成的ZIP文件
// CompressDownloadUtil.deleteFile(zipFilePath);
// } catch (IOException e) {
// Xlogger.error(XMsgError.buildSimple(CompressDownloadUtil.class.getName(), "downloadallfiles", e));
// }
 
 //-- 5、第二種方案:
 try {
 //-- 將多個文件壓縮寫進響應的輸出流
 CompressDownloadUtil.compressZip(files, response.getOutputStream());
 } catch (IOException e) {
 Xlogger.error(XMsgError.buildSimple(CompressDownloadUtil.class.getName(), "downloadallfiles", e));
 }
 
 }
 
 /**
 * 設置臨時生成的ZIP文件路徑
 *
 * @param fileName
 * @return 
 * @author hongwei.lian
 * @date 2018年9月7日 下午3:54:13
 */
 private String setZipFilePath(String fileName) {
 String zipPath = sysParamService.getCompressDownloadFilePath();
 File zipPathFile = new File(zipPath);
 if (!zipPathFile.exists()) {
 zipPathFile.mkdirs();
 }
 return zipPath + File.separator + fileName;
 }
 
 /**
 * 將fileCenters列表轉換為File列表
 *
 * @param fileCenters
 * @return 
 * @author hongwei.lian
 * @date 2018年9月6日 下午6:54:16
 */
 private List toFileList(List fileCenters) {
 return fileCenters.stream()
   .map(feFileCenter -> {
   //-- 獲取每個文件的路徑
   String filePath = this.getSysFilePath(feFileCenter.getFileTypeId());
   return new File(filePath + feFileCenter.fileLink());})
   .collect(Collectors.toList());
 }
 
 /**
 * 獲取文件類型對應存儲路徑
 *
 * @param fileTypeId
 * @return 
 * @author hongwei.lian
 * @date 2018年9月5日 下午2:01:53
 */
 private String getSysFilePath(Integer fileTypeId){
 SysParamPo sysmParam = sysParamService.getByParamKey(SysParamKey.FC_UPLOAD_ADDRESS.value);
 String filePath = Objects.nonNull(sysmParam) ? sysmParam.getParamValue() : "";
 return filePath + fileTypeId + File.separator;
 }
 
}

壓縮下載工具類

package com.huajin.jgoms.util;
 
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
 
import javax.servlet.http.HttpServletResponse;
 
import com.huajin.baymax.logger.XMsgError;
import com.huajin.baymax.logger.Xlogger;
 
/**
 * 壓縮下載工具類
 *
 * @author hongwei.lian
 * @date 2018年9月6日 下午6:34:56
 */
public class CompressDownloadUtil {
 
 private CompressDownloadUtil() {}
 
 /**
 * 設置下載響應頭
 *
 * @param response
 * @return 
 * @author hongwei.lian
 * @date 2018年9月7日 下午3:01:59
 */
 public static HttpServletResponse setDownloadResponse(HttpServletResponse response, String downloadName) {
 response.reset();
 response.setCharacterEncoding("utf-8");
 response.setContentType("application/octet-stream");
 response.setHeader("Content-Disposition", "attachment;fileName*=UTF-8''"+ downloadName);
 return response;
 }
 
 /**
 * 字符串轉換為整型數組
 *
 * @param param
 * @return 
 * @author hongwei.lian
 * @date 2018年9月6日 下午6:38:39
 */
 public static Integer[] toIntegerArray(String param) {
 return Arrays.stream(param.split(","))
  .map(Integer::valueOf)
  .toArray(Integer[]::new);
 }
 
 /**
 * 將多個文件壓縮到指定輸出流中
 *
 * @param files 需要壓縮的文件列表
 * @param outputStream 壓縮到指定的輸出流
 * @author hongwei.lian
 * @date 2018年9月7日 下午3:11:59
 */
 public static void compressZip(List files, OutputStream outputStream) {
 ZipOutputStream zipOutStream = null;
 try {
 //-- 包裝成ZIP格式輸出流
 zipOutStream = new ZipOutputStream(new BufferedOutputStream(outputStream));
 // -- 設置壓縮方法
 zipOutStream.setMethod(ZipOutputStream.DEFLATED);
 //-- 將多文件循環寫入壓縮包
 for (int i = 0; i < files.size(); i++) {
 File file = files.get(i);
 FileInputStream filenputStream = new FileInputStream(file);
 byte[] data = new byte[(int) file.length()];
 filenputStream.read(data);
 //-- 添加ZipEntry,并ZipEntry中寫入文件流,這里,加上i是防止要下載的文件有重名的導致下載失敗
 zipOutStream.putNextEntry(new ZipEntry(i + file.getName()));
 zipOutStream.write(data);
 filenputStream.close();
 zipOutStream.closeEntry();
 }
 } catch (IOException e) {
 Xlogger.error(XMsgError.buildSimple(CompressDownloadUtil.class.getName(), "downloadallfiles", e));
 } finally {
 try {
 if (Objects.nonNull(zipOutStream)) {
 zipOutStream.flush();
 zipOutStream.close();
 }
 if (Objects.nonNull(outputStream)) {
 outputStream.close();
 }
 } catch (IOException e) {
 Xlogger.error(XMsgError.buildSimple(CompressDownloadUtil.class.getName(), "downloadallfiles", e));
 }
 }
 }
 
 /**
 * 下載文件
 *
 * @param outputStream 下載輸出流
 * @param zipFilePath 需要下載文件的路徑
 * @author hongwei.lian
 * @date 2018年9月7日 下午3:27:08
 */
 public static void downloadFile(OutputStream outputStream, String zipFilePath) {
 File zipFile = new File(zipFilePath);
 if (!zipFile.exists()) {
 //-- 需要下載壓塑包文件不存在
 return ;
 }
 FileInputStream inputStream = null;
 try {
 inputStream = new FileInputStream(zipFile);
 byte[] data = new byte[(int) zipFile.length()];
 inputStream.read(data);
 outputStream.write(data);
 outputStream.flush();
 } catch (IOException e) {
 Xlogger.error(XMsgError.buildSimple(CompressDownloadUtil.class.getName(), "downloadZip", e));
 } finally {
 try {
 if (Objects.nonNull(inputStream)) {
 inputStream.close();
 }
 if (Objects.nonNull(outputStream)) {
 outputStream.close();
 }
 } catch (IOException e) {
 Xlogger.error(XMsgError.buildSimple(CompressDownloadUtil.class.getName(), "downloadZip", e));
 }
 }
 }
 
 /**
 * 刪除指定路徑的文件
 *
 * @param filepath 
 * @author hongwei.lian
 * @date 2018年9月7日 下午3:44:53
 */
 public static void deleteFile(String filepath) {
 File file = new File(filepath);
 deleteFile(file);
 }
 
 /**
 * 刪除指定文件
 *
 * @param file 
 * @author hongwei.lian
 * @date 2018年9月7日 下午3:45:58
 */
 public static void deleteFile(File file) {
 //-- 路徑為文件且不為空則進行刪除 
 if (file.isFile() && file.exists()) { 
 file.delete(); 
 } 
 }
 
}

測試

通過交易運營平臺上傳測試資料

java多文件壓縮下載的解決方法

登錄會員運營平臺進行下載

java多文件壓縮下載的解決方法

下載下來的ZIP格式為文件

java多文件壓縮下載的解決方法

解壓后,打開文件是否可用:

java多文件壓縮下載的解決方法

總結:

這個過程中出現了很多問題,后面會有文章逐步分析出錯和解決方案。

上述兩種方案都行,但是為了響應速度更快,可以省略壓縮成ZIP的臨時文件的時間,因此采用了第二種解決方案。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持創新互聯。


網頁名稱:java多文件壓縮下載的解決方法
文章出自:http://www.xueling.net.cn/article/ijcegi.html

其他資訊

在線咨詢
服務熱線
服務熱線:028-86922220
TOP
主站蜘蛛池模板: 日韩aⅴ在线观看 | 免费AV无码不卡在线观看 | 免费精品一区二区三区在线观看 | 777色淫网站女女免费 | 欧美三片| 撕开奶罩疯狂揉吮奶头 | 日韩av综合网 | 40岁成熟女人牲交片 | 久久伊人av | 天啪天天干 | 一区二区三区四区五区在线 | 国产精品熟女高潮视频 | japan凌虐bdsm日本 | 扒开粉嫩的小缝喷白浆h | 欧美一区二区三区四区视频 | 在线观看av日韩 | 成人一二三区视频 | 日本午夜免费视频 | 亚洲卡一卡二新区永久时长 | www.国产一区二区三区 | 92国产精品午夜福利免费 | 男人j捅女人p | 亚洲高清久久久 | 国产噜噜噜噜噜久久久久久久久 | 高清免费a级在线观看国产 无遮挡边摸边吃奶边做视频免费 | 国产91亚洲精品 | 国精品人妻无码一区二区三区性色 | xvideos国产在线观看 | 无遮挡边摸边吃奶边做视频免费 | 欧美GV肉片视频免费观看 | 脱美女内衣视频网站 | 免费一级特黄录像 | 亚洲精品在线成人 | 国产学生av娇小av毛片 | 最新国产在线播放 | 做爰吃奶全过程免费的网站 | 国内精品久久人妻朋友 | 欧美色xxxx | 粉嫩饱饱鱼一线天在线观看 | 国产在线观看第一页 | 亚洲国产综合精品在线一区 |