将文件数据作为 Bzip2 写入 servlet 响应的输出
我试图让 Tomcat 将 servlet 内容写为 bzip2 文件(也许是愚蠢的要求,但显然对于某些集成工作来说这是必要的)。我正在使用 Spring 框架,因此它位于 AbstractController 中。
正在使用 http://www.kohsuke.org/bzip2/ 中的 bzip2 库
我 可以很好地对内容进行 bzip 压缩,但是当文件写出时,它似乎包含一堆元数据,并且无法识别为 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 抽象控制器中的以下方法调用的
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception
我已经用不同的方法对其进行了一些尝试,包括直接写入 ServletOutput 但我很困惑并且找不到任何/网上很多例子。
任何以前遇到过此问题的人的任何建议将不胜感激。替代库/方法很好,但不幸的是它必须是 bzip2 的。
I'm trying to get Tomcat to write out the servlet contents as a bzip2 file (Silly requirement perhaps but it's apparently necessary for some integration work). I'm using the Spring framework so this is in an AbstractController.
I'm using the bzip2 library from http://www.kohsuke.org/bzip2/
I can get the contents bzipped fine but when the file is written out it seems to contain a bunch of meta data and is unrecognisable as a bzip2 file.
Here's what I'm doing
// 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+";)");
This is being called from the following method in the Spring abstractcontroller
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception
I've taken a few stabs at it in different approaches, including writing directly to the ServletOutput but I'm pretty stumped and can't find any/many examples online.
Any advice from anyone who's come across this before would be much appreciated. Alternative libraries/approaches are fine, but unfortunately it must be bzip2'd.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
发布的方法确实很奇怪。我已经重写,使其更有意义。尝试一下。
您看,只需用 CBZip2OutputStream 包装响应的输出流并将
byte[]
写入其中即可。您可能会碰巧在服务器日志中看到
IllegalStateException: Response已经提交
(顺便说一句,下载已正确发送),那么这意味着 Spring 之后正在尝试转发请求/响应。我不做 Spring,所以我无法详细介绍,但您至少应该指示 Spring 远离响应。不要让它进行映射、转发或其他任何操作。我认为返回null
就足够了。The posted approach is indeed weird. I've rewritten so that it makes more sense. Give it a try.
You see, just wrap the output stream of the response with
CBZip2OutputStream
and write thebyte[]
to it.You may happen to see
IllegalStateException: Response already committed
coming after this in the server logs (with the download being correctly sent by the way), then it means that Spring is trying to forward the request/response afterwards. I don't do Spring, so I can't go in detail, but you should at least instruct Spring to stay away from the response. Do not let it do a mapping, forward or whatever. I think returningnull
suffices.您可能会发现使用 CompressorStreamFactory来自 commons-compress 更容易一些。它是您已经使用的 Ant 版本的后代,最终与 BalusC 的示例有 2 行不同。
或多或少是图书馆偏好的问题。
You might find working with CompressorStreamFactory from commons-compress a little easier. It's a decedent of the Ant version you're already working with and ends up 2 lines different from BalusC's example.
More or less a matter of library preference.