Java后台实现浏览器一键导出下载zip压缩包
使用迭代器模式和组合模式实现浏览器一键导出下载为zip压缩包文件
由于项目需要,于是又想起之前看过的设计模式,于是便有了一键导出的想法。
思路简单明了。一步一步看下去就好。
1.创建组合对象
public abstract class FileComponent { /** * Description: 递归创建文件夹,或者文件 */ 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(); } }
此组合对象,可以是文件夹对象,也可是具体的文件对象,再后面调用中,不需要了解到底是一个文件夹还是一个文件(即组合模式的透明性)。
2.组合对象抽象类的实现
上述抽象类的实现如下:
public class ZipFileItem extends FileComponent{ //输入文件的路径 String inPath; //输出文件的路径 String outPath; //子节点文件信息 List<FileComponent> fileComponents = new ArrayList<FileComponent>(); //inPath 可以为null public ZipFileItem(String outPath){ this.outPath =outPath; } //压缩文件的源目录路径和压缩好的目标位置 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: 根据文件的绝对路径,在绝对的输出路径进行创建文件 * @param inPath 输入路径,如果是要根据已有的文件来创建,那么一定要传 * @param outPath 输出路径,如果是目录则不用 */ public static void createFile(String inPath,String outPath){ File fileIn = new File(inPath); File fileOut = new File(outPath); //如果目标文件已存在,则忽略,如果文件不存在 。则进行创建 if (!fileOut.exists()) { int lastSeparator = outPath.lastIndexOf(File.separator); String lastPart = outPath.substring(lastSeparator); //如果不是文件夹,则创建文件 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); } } //如果是文件夹则创建文件夹,如果父类文件夹不存在,那么也创建 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; } } } // 目录此时为空,可以删除 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.核心导出逻辑代码
public class exportMaterialToZipTemplate { @Resource private EnrichFileLevelsService enrichFileLevelsService; //根目录文件夹名称 or 下载浏览器文件名 private String downloadZipName; //根目录地址 private String savePath = "d:\\tempFile"; //根目录路径 private String superRootPath; //根目录对象 private FileComponent superRoot; //业务参数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.生成文件目录层级,即创建所有的文件(包括文件夹) 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 { //压缩文件临时路径 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); // 删除临时存放的文件夹 if (srcFile.exists()) { ConferenceFileUtils.deleteDir(srcFile); } //删除临时的压缩包 if (targetFile.exists()) { targetFile.delete(); } } catch (IOException e) { DevLog.error(e.getMessage()); } } //一键导出,外观模式 public void export() { enrichFileLevels(); createAllTheFiles(); compressAndDownload(); } }
5.丰富文件层级的接口
public interface EnrichFileLevelsService { public void enrichFileLevels(FileComponent superRoot,String superRootPath,ExportAllTheMaterialDTO paramDTO); }
不同的业务场景只要实现这接口,实现enrichFileLevels()方法,将实现此接口的
类实例传到exportMaterialToZipTemplate类的构造方法,然后调用exportMaterialToZipTemplate类实例的export()方法即可。即
new exportMaterialToZipTemplate(dtoParams,
enrichFileLevelsService, response).export();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
赞 (0)