服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|JavaScript|易语言|

服务器之家 - 编程语言 - Java教程 - Java后台实现浏览器一键导出下载zip压缩包

Java后台实现浏览器一键导出下载zip压缩包

2021-05-17 14:02TOBNO1 Java教程

这篇文章主要为大家详细介绍了Java后台实现浏览器一键导出下载zip压缩包,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

使用迭代器模式和组合模式实现浏览器一键导出下载为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

延伸 · 阅读

精彩推荐