我正在尝试让Tomcat以bzip2文件的形式写出servlet内容(也许是愚蠢的要求,但是显然对于某些集成工作而言是必需的)。我正在使用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这之后(通过正确的方式发送下载文件),这意味着Spring正在尝试随后转发请求/响应。我不做Spring,所以我不能详细介绍,但是您至少应该指示Spring远离响应。不要让它进行映射,转发或其他操作。我认为返回null就足够了。

关于java - 将文件数据作为Bzip2写入Servlet响应的输出,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2299758/

10-09 04:53