Java后臺實(shí)現(xiàn)瀏覽器一鍵導(dǎo)出下載zip壓縮包
使用迭代器模式和組合模式實(shí)現(xiàn)瀏覽器一鍵導(dǎo)出下載為zip壓縮包文件
由于項(xiàng)目需要,于是又想起之前看過的設(shè)計(jì)模式,于是便有了一鍵導(dǎo)出的想法。
思路簡單明了。一步一步看下去就好。
1.創(chuàng)建組合對象
public abstract class FileComponent { /** * Description: 遞歸創(chuàng)建文件夾,或者文件 */ public void mkFile(){ throw new UnsupportedOperationException(); } /** * Description: 獲取文件輸入路徑 */ public String getInPath(){ throw new UnsupportedOperationException(); } /** * Description: 獲取文件輸出路徑 */ public String getOutPath(){ throw new UnsupportedOperationException(); } /** * Description: 對于文件夾來說是可以add其他文件夾或者文件 */ public void add(FileComponent fileComponent){ throw new UnsupportedOperationException(); } }
此組合對象,可以是文件夾對象,也可是具體的文件對象,再后面調(diào)用中,不需要了解到底是一個(gè)文件夾還是一個(gè)文件(即組合模式的透明性)。
2.組合對象抽象類的實(shí)現(xiàn)
上述抽象類的實(shí)現(xiàn)如下:
public class ZipFileItem extends FileComponent{ //輸入文件的路徑 String inPath; //輸出文件的路徑 String outPath; //子節(jié)點(diǎn)文件信息 List<FileComponent> fileComponents = new ArrayList<FileComponent>(); //inPath 可以為null public ZipFileItem(String outPath){ this.outPath =outPath; } //壓縮文件的源目錄路徑和壓縮好的目標(biāo)位置 public ZipFileItem(String inPath,String outPath){ this.inPath =inPath; this.outPath =outPath; } public void add(FileComponent fileComponent){ fileComponents.add(fileComponent); } public void remove(FileComponent fileComponent){ fileComponents.remove(fileComponent); } @Override public String getInPath(){ return inPath; } @Override public String getOutPath(){ return outPath; } @Override public void mkFile(){ FileUtils.createFile(inPath, outPath); Iterator<FileComponent> iterator = fileComponents.iterator(); //如果是文件夾,那么還可以迭代文件及對象中的具體文件對象 while (iterator.hasNext()) { FileComponent fileComponent = iterator.next(); fileComponent.mkFile(); } } }
3.文件工具類
public class ConferenceFileUtils { /** * Description: 根據(jù)文件的絕對路徑,在絕對的輸出路徑進(jìn)行創(chuàng)建文件 * @param inPath 輸入路徑,如果是要根據(jù)已有的文件來創(chuàng)建,那么一定要傳 * @param outPath 輸出路徑,如果是目錄則不用 */ public static void createFile(String inPath,String outPath){ File fileIn = new File(inPath); File fileOut = new File(outPath); //如果目標(biāo)文件已存在,則忽略,如果文件不存在 。則進(jìn)行創(chuàng)建 if (!fileOut.exists()) { int lastSeparator = outPath.lastIndexOf(File.separator); String lastPart = outPath.substring(lastSeparator); //如果不是文件夾,則創(chuàng)建文件 if (lastPart.lastIndexOf(".")!=-1) { LoggerUtil.info("----------making concreteFile--------"+outPath); FileInputStream in = null; FileOutputStream out = null; File directory = null; try { directory = new File(outPath.substring(0, lastSeparator+1)); directory.mkdirs(); out=new FileOutputStream(fileOut); //如果源文件存在 if (fileIn.exists()) { in=new FileInputStream(fileIn); int len; byte[] buf=new byte[10240]; while((len=in.read(buf))>0){ out.write(buf,0,len); } out.close(); in.close(); in = null; } } catch (IOException e) { System.err.println("creating file failed!", e); } } //如果是文件夾則創(chuàng)建文件夾,如果父類文件夾不存在,那么也創(chuàng)建 else { System.err.println("----------making directory--------"+outPath); fileOut.mkdirs(); } } } //遞歸刪除文件夾以及文件 public static boolean deleteDir(File dir) { if (dir.isDirectory()) { String[] children = dir.list(); //遞歸刪除目錄中的子目錄 for (int i=0; i<children.length; i++) { boolean success = deleteDir(new File(dir, children[i])); if (!success) { return false; } } } // 目錄此時(shí)為空,可以刪除 return dir.delete(); } // 輸出文件對象到輸出流 public static void outputFile(File file, HttpServletResponse response) throws IOException { OutputStream out=null; FileInputStream in=null; try { byte[] src = new byte[1024]; out = response.getOutputStream(); in = new FileInputStream(file); int len=0; while ((len = in.read(src)) > 0) { out.write(src, 0, len); } out.flush(); out.close(); in.close(); } catch (IOException e) { throw new IOException(e); }finally{ if(null!=out){ FortifyUtil.commonReleasedResource(out); } if(null!=in){ FortifyUtil.commonReleasedResource(in); } } } }
4.核心導(dǎo)出邏輯代碼
public class exportMaterialToZipTemplate { @Resource private EnrichFileLevelsService enrichFileLevelsService; //根目錄文件夾名稱 or 下載瀏覽器文件名 private String downloadZipName; //根目錄地址 private String savePath = "d:\\tempFile"; //根目錄路徑 private String superRootPath; //根目錄對象 private FileComponent superRoot; //業(yè)務(wù)參數(shù)DTO private ExportAllTheMaterialDTO paramDTO; //response private HttpServletResponse response; public exportMaterialToZipTemplate(ExportAllTheMaterialDTO paramDTO,EnrichFileLevelsService enrichFileLevelsService,HttpServletResponse response) { this.downloadZipName = paramDTO.getDownloadZipName(); this.paramDTO = paramDTO; this.response = response; this.enrichFileLevelsService = enrichFileLevelsService; this.superRootPath =savePath+File.separator+downloadZipName; this.superRoot = new ZipFileItem(superRootPath); } //1.封裝根目錄 private void enrichFileLevels(){ enrichFileLevelsService.enrichFileLevels(superRoot,superRootPath,paramDTO); } //2.生成文件目錄層級,即創(chuàng)建所有的文件(包括文件夾) private void createAllTheFiles(){ if (null!=superRoot) { superRoot.mkFile(); } } //3.生成文件層級后后再壓縮后下載到瀏覽器 private void compressAndDownload() { File srcFile = new File(FortifyUtil.filterFileName(superRootPath)); String targetFilePath = savePath+File.separator+srcFile.getName()+".zip"; File targetFile = new File(FortifyUtil.filterFileName(targetFilePath)); ZipFileUtil.zipFiles(srcFile,targetFile); try { //壓縮文件臨時(shí)路徑 String downFileName = downloadZipName+".zip"; response.reset(); // 定義輸出類型 response.setContentType("application/octet-stream"); response.setHeader("content-disposition", "attachment;filename=" + new String(downFileName.getBytes("GBK"), "ISO-8859-1") + ";size=" + targetFile.length()); OutputFileUtil.outputFile(targetFile, response); // 刪除臨時(shí)存放的文件夾 if (srcFile.exists()) { ConferenceFileUtils.deleteDir(srcFile); } //刪除臨時(shí)的壓縮包 if (targetFile.exists()) { targetFile.delete(); } } catch (IOException e) { DevLog.error(e.getMessage()); } } //一鍵導(dǎo)出,外觀模式 public void export() { enrichFileLevels(); createAllTheFiles(); compressAndDownload(); } }
5.豐富文件層級的接口
public interface EnrichFileLevelsService { public void enrichFileLevels(FileComponent superRoot,String superRootPath,ExportAllTheMaterialDTO paramDTO); }
不同的業(yè)務(wù)場景只要實(shí)現(xiàn)這接口,實(shí)現(xiàn)enrichFileLevels()方法,將實(shí)現(xiàn)此接口的
類實(shí)例傳到exportMaterialToZipTemplate類的構(gòu)造方法,然后調(diào)用exportMaterialToZipTemplate類實(shí)例的export()方法即可。即
new exportMaterialToZipTemplate(dtoParams,
enrichFileLevelsService, response).export();
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot圖文并茂詳解如何引入mybatis與連接Mysql數(shù)據(jù)庫
這篇文章主要介紹了SpringBoot如何引入mybatis與連接Mysql數(shù)據(jù)庫,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07JavaWeb中使用JavaMail實(shí)現(xiàn)發(fā)送郵件功能實(shí)例詳解
這篇文章主要介紹了JavaWeb中使用JavaMail實(shí)現(xiàn)發(fā)送郵件功能的實(shí)例代碼,非常不錯(cuò)具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-05-05多數(shù)據(jù)源如何實(shí)現(xiàn)事務(wù)管理
Spring中涉及三個(gè)核心事務(wù)處理接口:PlatformTransactionManager、TransactionDefinition和TransactionStatus,PlatformTransactionManager提供事務(wù)操作的基本方法,如獲取事務(wù)、提交和回滾2024-09-09IDEA的Web項(xiàng)目右鍵無法創(chuàng)建Servlet問題解決辦法
這篇文章主要介紹了IDEA的Web項(xiàng)目右鍵無法創(chuàng)建Servlet問題解決辦法的相關(guān)資料,在IDEA中新建Servlet時(shí)發(fā)現(xiàn)缺失選項(xiàng),可以通過在pom.xml文件中添加servlet依賴解決,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2024-10-10Java中的引用和動(dòng)態(tài)代理的實(shí)現(xiàn)詳解
這篇文章主要介紹了Java中的引用和動(dòng)態(tài)代理的實(shí)現(xiàn)詳解,涉及Java中的引用類型,JVMGC的可達(dá)性分析,代理模式等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11