Java后台实现浏览器一键导出下载zip压缩包
时间:2018-07-14
这篇文章主要为大家详细介绍了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();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
- GitHub敏感信息扫描工具
- Java数据结构和算法(九)——高级排序
- Java数据结构和算法(十一)——红黑树
- Entity Framework Core 之数据库迁移
- 常见Web源码泄露总结
- 浅析Entity Framework Core2.0的日志记录与动态查询条件
- ASP.NET Core中使用IOC三部曲(三.采用替换后的Autofac来实现AOP拦截)
- 【weakfilescan】敏感文件扫描工具
- ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)
- ASP.NET Core中使用IOC三部曲(一.使用ASP.NET Core自带的IOC容器)
- CVE-2017-11882漏洞复现
- ASP.NET Core使用静态文件、目录游览与MIME类型管理
- Python 黑客——使用Python破解门禁系统
- ASP.NET Core文件上传与下载(多种上传方式)
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Linux命令行快速技巧之定位一个文件的办法
- ubuntu中python调用C/C++办法之动态链接库详解
- linux中使用boost.python调用c++动态库的办法
- 在Linux系统下上传项目到码云的办法
- PHP global全局变量经典应用与注意事项分析【附$GLOBALS用法对比】 原创
- Linux(Ubuntu 18.04)上安装Anaconda步骤详解
- php web环境和命令行环境下查找php.ini的位置
- PHP大文件分块上传功能实例详解
- Linux 命令行通配符及转义符的实现
- Python爬虫抓取指定网页图片代码实例
- PHP变量作用域(全局变量&局部变量)&global&static关键字用法实例分析
- CentOS 7 安装Chrome浏览器的方法
- PHP高级编程之消息队列原理与实现方法详解
- thinkphp5.1框架模板布局与模板继承用法分析
- Linux内核设备驱动之内存管理笔记整理