簡體   English   中英

將文件數據作為Bzip2寫入Servlet響應的輸出

[英]Write file data as Bzip2 to output of servlet response

我正在嘗試讓Tomcat將servlet內容作為bzip2文件寫出(也許是傻乎乎的要求,但是顯然對於某些集成工作而言是必需的)。 我正在使用Spring框架,所以它在AbstractController中。

我正在使用http://www.kohsuke.org/bzip2/中的bzip2庫

我可以很好地壓縮內容,但是當文件被寫出時,它似乎包含了一堆元數據,並且無法識別為bzip2文件。

這就是我在做什么

// get the contents of my file as a byte array
byte[] fileData =  file.getStoredFile();

ByteArrayOutputStream baos = new ByteArrayOutputStream();

//create a bzip2 output stream to the byte output and write the file data to it             
CBZip2OutputStream bzip = null;
try {
     bzip = new CBZip2OutputStream(baos);
     bzip.write(fileData, 0, fileData.length);
     bzip.close();  
} catch (IOException ex) {
     ex.printStackTrace();
}
byte[] bzippedOutput = baos.toByteArray();
System.out.println("bzipcompress_output:\t" + bzippedOutput.length);

//now write the byte output to the servlet output
//setting content disposition means the file is downloaded rather than displayed
int outputLength = bzippedOutput.length;
String fileName = file.getFileIdentifier();
response.setBufferSize(outputLength);
response.setContentLength(outputLength);
response.setContentType("application/x-bzip2");
response.setHeader("Content-Disposition",
                                       "attachment; filename="+fileName+";)");

從Spring abstractcontroller中的以下方法中調用此方法

protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)  throws Exception

我以不同的方式對它進行了一些測試,包括直接寫入ServletOutput,但是我很困惑,無法在線找到任何/很多示例。

以前遇到過此問題的任何人的任何建議都將不勝感激。 可以選擇其他庫/方法,但是很遺憾,必須使用bzip2'd。

發布的方法確實很奇怪。 我已經重寫了它,使它更有意義。 試試看。

String fileName = file.getFileIdentifier();
byte[] fileData = file.getStoredFile(); // BTW: Any chance to get this as InputStream? This is namely memory hogging.

response.setContentType("application/x-bzip2");
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

OutputStream output = null;

try {
     output = new CBZip2OutputStream(response.getOutputStream());
     output.write(fileData);
} finally {
     output.close();
}

您會看到,只需用CBZip2OutputStream包裝響應的輸出流,然后將byte[]寫入其中即可。

您可能會碰巧看到IllegalStateException: Response already committed在服務器日志中此之后IllegalStateException: Response already committedIllegalStateException: Response already committed (通過正確的方式正確發送了下載內容),這意味着Spring稍后嘗試轉發請求/響應。 我不做Spring,所以我不能詳細介紹,但是您至少應該指示Spring 遠離響應。 不要讓它進行映射,轉發或其他操作。 我認為返回null就足夠了。

您可能會發現從commons-compress使用CompressorStreamFactory更加容易。 它是您已經在使用的Ant版本的后繼者,最終與BalusC的示例不同,只有兩行內容。

或多或少取決於圖書館的偏好。

OutputStream out = null;
try {
    out = new CompressorStreamFactory().createCompressorOutputStream("bzip2", response.getOutputStream());
    IOUtils.copy(new FileInputStream(input), out); // assuming you have access to a File.
} finally {
    out.close();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM