我們目前正在研究將資料存檔并將其作為用戶回傳給用戶的服務 ZipOutputStream. 我們目前正在尋找的是在服務器端出現問題時完全終止操作的選項。對于我們當前的實作(只是關閉回應輸出流),錯誤會導致用戶端的 zip 格式錯誤,但在嘗試解壓縮之前無法判斷存檔是否格式錯誤。所需的行為類似于下載終止(例如,從瀏覽器的角度來看,它會導致下載失敗指示(紅十字圖示或類似的東西,取決于瀏覽器)明確告訴用戶出現問題)。我們正在使用 Spring Boot,因此任何 Java 代碼示例都將不勝感激,但如果您了解底層HTTP負責這種行為的機制,并且可以指向正確的方向,這也將不勝感激。這是我們目前所擁有的(輸出是 Spring REST 控制器 ( HttpServletResponse.getOutputStream())的回應輸出流:
try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
try {
for (ZipRecordFile fileInfo : zipRecord.listZipFileOverride()) {
InputStream fileStream = getFileStream(fileInfo.s3region(), fileInfo.s3bucket(),
fileInfo.s3key());
ZipEntry zipEntry = new ZipEntry(fileInfo.fileName());
zipOutputStream.putNextEntry(zipEntry);
fileStream.transferTo(zipOutputStream);
}
}
catch (Exception e) {
outputStream.close();
}
}
uj5u.com熱心網友回復:
沒有一種(干凈的)方法可以做你想做的事:
一旦您開始將 ZIP 檔案寫入輸出流,再更改 HTTP 回應代碼為時已晚。回應代碼在回應開始時發送。
因此,HTTP 服務器沒有正確的方法來告訴 HTTP 客戶端:“嘿...忽略我發送給您的那個 ZIP 檔案,因為它已損壞”。
那么有哪些替代方案呢?
在服務器端,將整個 ZIP 創建為記憶體物件或將其寫入臨時檔案。如果成功,請發送 2xx 回應,后跟 ZIP 資料。如果失敗,請發送 4xx 或 5xx 回應。
主要問題是您需要足夠的記憶體或檔案系統空間來保存 ZIP 檔案。
重新設計您的 HTTP API,以便客戶端可以發送第二個請求來檢查第一個請求的回應是否包含完整的 ZIP 檔案。
您也許能夠利用 MIME 多部分編碼。格式良好的 MIME 多部分的每個部分都有一個開始標記和一個結束標記。您可以嘗試讓您的網路應用程式“手動”構建包含 ZIP 的多部分流。如果它決定必須中止 ZIP,它可以只關閉輸出流而不添加所需的結束標記。
這樣做的主要問題是您依賴于客戶端的 HTTP 堆疊來告訴瀏覽器(或其他任何東西)多部分已損壞。此外,瀏覽器(或其他任何東西)不得將部分(即損壞的)ZIP 檔案傳遞??給用戶。我不確定您是否可以依靠(特定的)網路瀏覽器來做到這一點。
如果您在客戶端通過自定義代碼運行下載,則可以想象實作自己的封裝協議。效果與 3 相同……但您不會濫用 MIME 規范。
uj5u.com熱心網友回復:
我認為你應該拋出例外而不是處理它。
使用 catch 塊,您正在處理例外。
catch (Exception e) {
outputStream.close();
}
此外,由于您的代碼正在使用try-with-resources塊,您不應該需要另一個 try 塊并且不需要顯式 close zipOutputStream。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/395173.html
