サーブレット応答の出力にBzip2でのように書き込み、ファイルデータ
-
21-09-2019 - |
質問
私は(おそらく愚かな要件が、それは、いくつかの統合作業のために明らかに必要です)TomcatはBZIP2ファイルとしてサーブレットの内容を書き出すために取得しようとしています。これはAbstractControllerであるので、私は、Springフレームワークを使用しています。
私は http://www.kohsuke.org/bzip2/からbzip2のライブラリを使用していますA>
私は内容が罰金を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+";)");
これは春に、以下のメソッドから呼び出されている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
は(正しく経由で送信され、ダウンロードして)サーバーのログには、この後に来るのを見ることが起こることがあり、それは春がその後の要求/応答を転送しようとしていることを意味します。離れての応答からの滞在に少なくとも春の指示、私は詳細に行くことができない、しかし、あなたがする必要がありますので、私は、春をしません。前方または何でも、それがマッピングを行うことはできません。私はnull
ので十分に返すだと思います。
他のヒント
あなたは CompressorStreamFactoryで作業を見つけるかもしれません からコモンズ、圧縮少し楽にする。それはあなたがすでにBalusCの例とは異なると協力し、2つのラインアップが終了しているAntのバージョンの被相続人です。
多かれ少なかれライブラリ好みの問題。
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();
}