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 fileComponents = new ArrayList();

    //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 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; inew 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();

如有问题、请多多交流。尊重原创,转载请注明出处,谢谢!

https://blog.csdn.net/uniquewonderq/article/details/79655835

你可能感兴趣的:(java,设计模式)