Java后台实现浏览器一键导出下载zip压缩包
程序员文章站
2023-12-21 20:55:52
使用迭代器模式和组合模式实现浏览器一键导出下载为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();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。