使用迭代器模式和组合模式实现浏览器一键导出下载为zip压缩包文件
由于项目需要,于是又想起之前看过的设计模式,于是便有了一键导出的想法。
思路简单明了。一步一步看下去就好。
1.创建组合对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
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.组合对象抽象类的实现
上述抽象类的实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
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.文件工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
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.核心导出逻辑代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
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.丰富文件层级的接口
1 2 3 |
public interface enrichfilelevelsservice { public void enrichfilelevels(filecomponent superroot,string superrootpath,exportallthematerialdto paramdto); } |
不同的业务场景只要实现这接口,实现enrichfilelevels()方法,将实现此接口的
类实例传到exportmaterialtoziptemplate类的构造方法,然后调用exportmaterialtoziptemplate类实例的export()方法即可。即
new exportmaterialtoziptemplate(dtoparams,
enrichfilelevelsservice, response).export();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
原文链接:https://blog.csdn.net/uniquewonderq/article/details/79655835
查看更多关于Java后台实现浏览器一键导出下载zip压缩包的详细内容...