Java后台实现浏览器一键导出下载zip压缩包
使用迭代器模式和组合模式实现浏览器一键导出下载为zip压缩包文件
由于项目需要,于是又想起之前看过的设计模式,于是便有了一键导出的想法。
思路简单明了。一步一步看下去就好。
1.创建组合对象
publicabstractclassFileComponent{
/**
*Description:递归创建文件夹,或者文件
*/
publicvoidmkFile(){
thrownewUnsupportedOperationException();
}
/**
*Description:获取文件输入路径
*/
publicStringgetInPath(){
thrownewUnsupportedOperationException();
}
/**
*Description:获取文件输出路径
*/
publicStringgetOutPath(){
thrownewUnsupportedOperationException();
}
/**
*Description:对于文件夹来说是可以add其他文件夹或者文件
*/
publicvoidadd(FileComponentfileComponent){
thrownewUnsupportedOperationException();
}
}
此组合对象,可以是文件夹对象,也可是具体的文件对象,再后面调用中,不需要了解到底是一个文件夹还是一个文件(即组合模式的透明性)。
2.组合对象抽象类的实现
上述抽象类的实现如下:
publicclassZipFileItemextendsFileComponent{
//输入文件的路径
StringinPath;
//输出文件的路径
StringoutPath;
//子节点文件信息
ListfileComponents=newArrayList();
//inPath可以为null
publicZipFileItem(StringoutPath){
this.outPath=outPath;
}
//压缩文件的源目录路径和压缩好的目标位置
publicZipFileItem(StringinPath,StringoutPath){
this.inPath=inPath;
this.outPath=outPath;
}
publicvoidadd(FileComponentfileComponent){
fileComponents.add(fileComponent);
}
publicvoidremove(FileComponentfileComponent){
fileComponents.remove(fileComponent);
}
@Override
publicStringgetInPath(){
returninPath;
}
@Override
publicStringgetOutPath(){
returnoutPath;
}
@Override
publicvoidmkFile(){
FileUtils.createFile(inPath,outPath);
Iteratoriterator=fileComponents.iterator();
//如果是文件夹,那么还可以迭代文件及对象中的具体文件对象
while(iterator.hasNext()){
FileComponentfileComponent=iterator.next();
fileComponent.mkFile();
}
}
}
3.文件工具类
publicclassConferenceFileUtils{
/**
*Description:根据文件的绝对路径,在绝对的输出路径进行创建文件
*@paraminPath输入路径,如果是要根据已有的文件来创建,那么一定要传
*@paramoutPath输出路径,如果是目录则不用
*/
publicstaticvoidcreateFile(StringinPath,StringoutPath){
FilefileIn=newFile(inPath);
FilefileOut=newFile(outPath);
//如果目标文件已存在,则忽略,如果文件不存在。则进行创建
if(!fileOut.exists()){
intlastSeparator=outPath.lastIndexOf(File.separator);
StringlastPart=outPath.substring(lastSeparator);
//如果不是文件夹,则创建文件
if(lastPart.lastIndexOf(".")!=-1){
LoggerUtil.info("----------makingconcreteFile--------"+outPath);
FileInputStreamin=null;
FileOutputStreamout=null;
Filedirectory=null;
try{
directory=newFile(outPath.substring(0,lastSeparator+1));
directory.mkdirs();
out=newFileOutputStream(fileOut);
//如果源文件存在
if(fileIn.exists()){
in=newFileInputStream(fileIn);
intlen;
byte[]buf=newbyte[10240];
while((len=in.read(buf))>0){
out.write(buf,0,len);
}
out.close();
in.close();
in=null;
}
}catch(IOExceptione){
System.err.println("creatingfilefailed!",e);
}
}
//如果是文件夹则创建文件夹,如果父类文件夹不存在,那么也创建
else{
System.err.println("----------makingdirectory--------"+outPath);
fileOut.mkdirs();
}
}
}
//递归删除文件夹以及文件
publicstaticbooleandeleteDir(Filedir){
if(dir.isDirectory()){
String[]children=dir.list();
//递归删除目录中的子目录
for(inti=0;i0){
out.write(src,0,len);
}
out.flush();
out.close();
in.close();
}catch(IOExceptione){
thrownewIOException(e);
}finally{
if(null!=out){
FortifyUtil.commonReleasedResource(out);
}
if(null!=in){
FortifyUtil.commonReleasedResource(in);
}
}
}
}
4.核心导出逻辑代码
publicclassexportMaterialToZipTemplate{
@Resource
privateEnrichFileLevelsServiceenrichFileLevelsService;
//根目录文件夹名称or下载浏览器文件名
privateStringdownloadZipName;
//根目录地址
privateStringsavePath="d:\\tempFile";
//根目录路径
privateStringsuperRootPath;
//根目录对象
privateFileComponentsuperRoot;
//业务参数DTO
privateExportAllTheMaterialDTOparamDTO;
//response
privateHttpServletResponseresponse;
publicexportMaterialToZipTemplate(ExportAllTheMaterialDTOparamDTO,EnrichFileLevelsServiceenrichFileLevelsService,HttpServletResponseresponse){
this.downloadZipName=paramDTO.getDownloadZipName();
this.paramDTO=paramDTO;
this.response=response;
this.enrichFileLevelsService=enrichFileLevelsService;
this.superRootPath=savePath+File.separator+downloadZipName;
this.superRoot=newZipFileItem(superRootPath);
}
//1.封装根目录
privatevoidenrichFileLevels(){
enrichFileLevelsService.enrichFileLevels(superRoot,superRootPath,paramDTO);
}
//2.生成文件目录层级,即创建所有的文件(包括文件夹)
privatevoidcreateAllTheFiles(){
if(null!=superRoot){
superRoot.mkFile();
}
}
//3.生成文件层级后后再压缩后下载到浏览器
privatevoidcompressAndDownload(){
FilesrcFile=newFile(FortifyUtil.filterFileName(superRootPath));
StringtargetFilePath=savePath+File.separator+srcFile.getName()+".zip";
FiletargetFile=newFile(FortifyUtil.filterFileName(targetFilePath));
ZipFileUtil.zipFiles(srcFile,targetFile);
try{
//压缩文件临时路径
StringdownFileName=downloadZipName+".zip";
response.reset();
//定义输出类型
response.setContentType("application/octet-stream");
response.setHeader("content-disposition","attachment;filename="
+newString(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(IOExceptione){
DevLog.error(e.getMessage());
}
}
//一键导出,外观模式
publicvoidexport(){
enrichFileLevels();
createAllTheFiles();
compressAndDownload();
}
}
5.丰富文件层级的接口
publicinterfaceEnrichFileLevelsService{
publicvoidenrichFileLevels(FileComponentsuperRoot,StringsuperRootPath,ExportAllTheMaterialDTOparamDTO);
}
不同的业务场景只要实现这接口,实现enrichFileLevels()方法,将实现此接口的
类实例传到exportMaterialToZipTemplate类的构造方法,然后调用exportMaterialToZipTemplate类实例的export()方法即可。即
newexportMaterialToZipTemplate(dtoParams,
enrichFileLevelsService,response).export();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。