Java后臺實現(xiàn)瀏覽器一鍵導(dǎo)出下載zip壓縮包
使用迭代器模式和組合模式實現(xiàn)瀏覽器一鍵導(dǎo)出下載為zip壓縮包文件
由于項目需要,于是又想起之前看過的設(shè)計模式,于是便有了一鍵導(dǎo)出的想法。
思路簡單明了。一步一步看下去就好。
1.創(chuàng)建組合對象
public abstract class FileComponent {
/**
* Description: 遞歸創(chuàng)建文件夾,或者文件
*/
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();
}
}
此組合對象,可以是文件夾對象,也可是具體的文件對象,再后面調(diào)用中,不需要了解到底是一個文件夾還是一個文件(即組合模式的透明性)。
2.組合對象抽象類的實現(xiàn)
上述抽象類的實現(xiàn)如下:
public class ZipFileItem extends FileComponent{
//輸入文件的路徑
String inPath;
//輸出文件的路徑
String outPath;
//子節(jié)點文件信息
List<FileComponent> fileComponents = new ArrayList<FileComponent>();
//inPath 可以為null
public ZipFileItem(String outPath){
this.outPath =outPath;
}
//壓縮文件的源目錄路徑和壓縮好的目標(biāo)位置
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: 根據(jù)文件的絕對路徑,在絕對的輸出路徑進(jìn)行創(chuàng)建文件
* @param inPath 輸入路徑,如果是要根據(jù)已有的文件來創(chuàng)建,那么一定要傳
* @param outPath 輸出路徑,如果是目錄則不用
*/
public static void createFile(String inPath,String outPath){
File fileIn = new File(inPath);
File fileOut = new File(outPath);
//如果目標(biāo)文件已存在,則忽略,如果文件不存在 。則進(jìn)行創(chuàng)建
if (!fileOut.exists()) {
int lastSeparator = outPath.lastIndexOf(File.separator);
String lastPart = outPath.substring(lastSeparator);
//如果不是文件夾,則創(chuàng)建文件
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);
}
}
//如果是文件夾則創(chuàng)建文件夾,如果父類文件夾不存在,那么也創(chuàng)建
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.核心導(dǎo)出邏輯代碼
public class exportMaterialToZipTemplate {
@Resource
private EnrichFileLevelsService enrichFileLevelsService;
//根目錄文件夾名稱 or 下載瀏覽器文件名
private String downloadZipName;
//根目錄地址
private String savePath = "d:\\tempFile";
//根目錄路徑
private String superRootPath;
//根目錄對象
private FileComponent superRoot;
//業(yè)務(wù)參數(shù)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.生成文件目錄層級,即創(chuàng)建所有的文件(包括文件夾)
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());
}
}
//一鍵導(dǎo)出,外觀模式
public void export() {
enrichFileLevels();
createAllTheFiles();
compressAndDownload();
}
}
5.豐富文件層級的接口
public interface EnrichFileLevelsService {
public void enrichFileLevels(FileComponent superRoot,String superRootPath,ExportAllTheMaterialDTO paramDTO);
}
不同的業(yè)務(wù)場景只要實現(xiàn)這接口,實現(xiàn)enrichFileLevels()方法,將實現(xiàn)此接口的
類實例傳到exportMaterialToZipTemplate類的構(gòu)造方法,然后調(diào)用exportMaterialToZipTemplate類實例的export()方法即可。即
new exportMaterialToZipTemplate(dtoParams,
enrichFileLevelsService, response).export();
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
spring聲明式事務(wù) @Transactional 不回滾的多種情況以及解決方案
本文主要介紹了spring聲明式事務(wù) @Transactional 不回滾的多種情況以及解決方案,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11
Linux系統(tǒng)中查詢JDK安裝目錄的幾種常用方法
這篇文章主要介紹了Linux系統(tǒng)中查詢JDK安裝目錄的幾種常用方法,方法分別是通過update-alternatives、Java命令、環(huán)境變量及目錄搜索,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-07-07
深入分析Comparable與Comparator及Clonable三個Java接口
接口不是類,而是對類的一組需求描述,這些類要遵從接口描述的統(tǒng)一格式進(jìn)行定義,這篇文章主要為大家詳細(xì)介紹了Java的Comparable,Comparator和Cloneable的接口,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-05-05

