Use iterator mode and combination mode to implement one-click export and download to zip compressed package files in the browser
Because of the project's needs, I remembered the design pattern I had seen before, so I had the idea of one-click export.
The idea is simple and clear. Just watch it step by step.
1. Create a composite object
public abstract class FileComponent { /** * Description: Recursively create a folder, or file */ public void mkFile(){ throw new UnsupportedOperationException(); } /** * Description: Get the file input path */ public String getInPath(){ throw new UnsupportedOperationException(); } /** * Description: Get the file output path */ public String getOutPath(){ throw new UnsupportedOperationException(); } /** * Description: For folders, you can add other folders or files*/ public void add(FileComponent fileComponent){ throw new UnsupportedOperationException(); }}This combination object can be a folder object or a specific file object. In the subsequent call, there is no need to know whether it is a folder or a file (that is, the transparency of the combination mode).
2. Implementation of composite object abstract class
The implementation of the above abstract class is as follows:
public class ZipFileItem extends FileComponent{ //Path of input file String inPath; //Path of output file String outPath; //Subnode file information List<FileComponent> fileComponents = new ArrayList<FileComponent>(); //inPath can be null public ZipFileItem(String outPath){ this.outPath =outPath; } //The source directory path of the compressed file and the compressed target location 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(); //If it is a folder, you can also iterate over the file and the specific file object in the object while (iterator.hasNext()) { FileComponent fileComponent = iterator.next(); fileComponent.mkFile(); } }}3. File tool class
public class ConferenceFileUtils { /** * Description: Create a file in the absolute output path based on the absolute path of the file * @param inPath input path. If you want to create it based on an existing file, then you must pass * @param outPath output path. If it is a directory, you do not use */ public static void createFile(String inPath,String outPath){ File fileIn = new File(inPath); File fileOut = new File(outPath); //If the target file already exists, ignore it if the file does not exist. Then create if (!fileOut.exists()) { int lastSeparator = outPath.lastIndexOf(File.separator); String lastPart = outPath.substring(lastSeparator); //If it is not a folder, create the file 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 the source file exists 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); } } //If it is a folder, create a folder. If the parent class folder does not exist, then create an else { System.err.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ boolean success = deleteDir(new File(dir, children[i])); if (!success) { return false; } } } // The directory is empty at this time, you can delete return dir.delete(); } // The output file object to the output stream 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. Core export logic code
public class exportMaterialToZipTemplate { @Resource private EnrichFileLevelsService enrichFileLevelsService; //Root directory folder name or download browser file name private String downloadZipName; //Root directory address private String savePath = "d://tempFile"; //Root directory path private String superRootPath; //Root directory object private FileComponent superRoot; //Business parameter 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. Encapsulate the root directory private void enrichFileLevels(){ enrichFileLevelsService.enrichFileLevels(superRoot, superRootPath, paramDTO); } //2. Generate the file directory level, that is, create all files (including folders) private void createAllTheFiles(){ if (null!=superRoot) { superRoot.mkFile(); } } //3. After generating the file level, then compress it and download it to the browser 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 { //Compress file temporary path String downFileName = downloadZipName+".zip"; response.reset(); // Define the output type 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); // Delete the folder temporarily stored if (srcFile.exists()) { ConferenceFileUtils.deleteDir(srcFile); } //Delete the temporary compressed package if (targetFile.exists()) { targetFile.delete(); } } catch (IOException e) { DevLog.error(e.getMessage()); } } //One-click export, appearance mode public void export() { enrichFileLevels(); createAllTheFiles(); compressAndDownload(); }}5. Enrich file-level interfaces
public interface EnrichFileLevelsService { public void enrichFileLevels(FileComponent superRoot,String superRootPath,ExportAllTheMaterialDTO paramDTO);} In different business scenarios, just implement this interface, implement the enrichFileLevels() method, pass the class instance that implements this interface to the constructor method of the exportMaterialToZipTemplate class, and then call the export() method of the exportMaterialToZipTemplate class instance. Right now
new exportMaterialToZipTemplate(dtoParams,
enrichFileLevelsService, response).export();
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.