首页 > 开发 > Java > 正文

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

2024-07-14 08:41:35
字体:
来源:转载
供稿:网友

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VeVb武林网。


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表