Class ZipFileResponseBuilder
java.lang.Object
io.leandev.appfuse.file.ZipFileResponseBuilder
ZIP 檔案下載 Response 建構器(支援 Range Request)
先產生 ZIP 暫存檔,再提供下載。適用於:
- 大型 ZIP 檔案需要斷點續傳
- 需要支援 Range Request 的場景
運作方式:
- 建立暫存 ZIP 檔案
- 使用
RangeUtils.evaluate(String, long)評估 Range header - 回傳完整檔案(200 OK)、部分內容(206 Partial Content)或無法滿足(416)
- 有 body 的回應在串流關閉時刪除暫存檔;
HEAD、416與產生失敗在build()內刪除
驗證器:ZIP 每次請求都重新產生,entry 時間戳使兩次產生的位元組不同,因此不送 ETag;
帶 If-Range 的請求一律回完整內容,避免續傳時接上不同次產生的位元組。沒有 If-Range 的 Range
只對本次產生的檔案評估,跨請求拼接的一致性不保證——需要安全續傳時,先以 FileStorage 保存,
再以 FileResponseBuilder 下載。
只服務 GET 與 HEAD;其他方法在產生暫存檔之前丟出 IllegalArgumentException。
使用範例
@GetMapping("/products/{id}/images.zip")
public ResponseEntity<Resource> downloadImages(
@PathVariable String id, HttpServletRequest request) {
Product product = productService.findById(id);
String partition = TenantContext.getCurrentTenantId();
ZipFileResponseBuilder builder = ZipFileResponseBuilder.create("product-images.zip");
// 新增主圖
if (product.getMainImage() != null) {
builder.addFile("main-image.jpg", fileStorage, partition,
product.getMainImage().getFileId());
}
// 新增副圖
int i = 1;
for (FileDescriptor fd : product.getGalleryImages()) {
builder.addFile("gallery-" + i++ + ".jpg", fileStorage, partition, fd.getFileId());
}
return builder.request(request).build();
}
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionaddFile(String entryName, FileStorage fileStorage, String partition, String fileId) 新增檔案到 ZIP(使用 FileStorage)addFile(String entryName, Supplier<InputStream> contentSupplier) 新增檔案到 ZIPorg.springframework.http.ResponseEntity<org.springframework.core.io.Resource> build()建構 ResponseEntitystatic ZipFileResponseBuilder建立 ZipFileResponseBuilderint取得檔案數量booleanhasFiles()檢查是否有檔案設定請求的If-Rangeheader;ZIP 沒有驗證器,出現任何值(含空值)都回完整內容method(org.springframework.http.HttpMethod method) 設定請求方法;未設定時視為GET設定 Range header(支援部分內容下載)request(jakarta.servlet.http.HttpServletRequest request) 由目前請求讀取方法、Range與If-Range
-
Method Details
-
create
建立 ZipFileResponseBuilder- Parameters:
zipFilename- ZIP 檔案名稱(如 "images.zip")- Returns:
- ZipFileResponseBuilder 實例
-
addFile
新增檔案到 ZIP- Parameters:
entryName- ZIP 內的檔案名稱contentSupplier- InputStream 供應者- Returns:
- this
-
addFile
public ZipFileResponseBuilder addFile(String entryName, FileStorage fileStorage, String partition, String fileId) 新增檔案到 ZIP(使用 FileStorage)- Parameters:
entryName- ZIP 內的檔案名稱fileStorage- FileStorage 實例partition- 儲存分區鍵fileId- 檔案 ID- Returns:
- this
-
request
由目前請求讀取方法、Range與If-Range- Parameters:
request- 目前請求- Returns:
- this
-
method
設定請求方法;未設定時視為
GET只接受
GET與HEAD,其他方法在build()丟出IllegalArgumentException。- Parameters:
method- 請求方法- Returns:
- this
-
ifRange
設定請求的If-Rangeheader;ZIP 沒有驗證器,出現任何值(含空值)都回完整內容- Parameters:
ifRange- 請求的 If-Range header 值;null表示請求沒有 If-Range- Returns:
- this
-
range
設定 Range header(支援部分內容下載)- Parameters:
rangeHeader- HTTP Range header 值(如 "bytes=0-1000"),可為 null- Returns:
- this
-
hasFiles
public boolean hasFiles()檢查是否有檔案- Returns:
- 是否有檔案
-
getFileCount
public int getFileCount()取得檔案數量- Returns:
- 檔案數量
-
build
public org.springframework.http.ResponseEntity<org.springframework.core.io.Resource> build()建構 ResponseEntity
產生 ZIP 暫存檔並回傳下載回應。支援 Range Request(見類別說明的驗證器限制)。
- Returns:
- ResponseEntity with Resource
- Throws:
IllegalArgumentException- 請求方法不是GET或HEAD
-