0

ファイルのダウンロードを簡単な方法で書きました。

@ResourceMapping(value = "content")
public void download(ResourceRequest request, ResourceResponse response) {
//...
SerializableInputStream serializableInputStream = someService.getSerializableInputStream(id_of_some_file);

response.addProperty(HttpHeaders.CACHE_CONTROL, "max-age=3600, must-revalidate");
response.setContentType(contentType);
response.addProperty(HttpHeaders.CONTENT_TYPE, contentType);
response.addProperty(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''"
    + URLEncoder.encode(fileName, "UTF-8"));

OutputStream outputStream = response.getPortletOutputStream();
byte[] parcel = new byte[4096];

while (serializableInputStream.read(parcel) > 0)
    outputStream.write(parcel);

outputStream.flush();
serializableInputStream.close();
outputStream.close();
//...
}

JavaDocsSerializableInputStreamで説明されています。これにより、InputStream をシリアル化して、たとえばリモート処理で渡すことができます。

一度にすべてのバイトではなく、入力から読み取って出力に書き込みます。残念ながら、ポートレットはコンテンツを「ストリーミング」していません。ファイル (画像など) は、入力ストリーム全体を読み取った後にのみブラウザに送信されます。ファイルがデータベースから (ライブ ログから) 読み取られているのがわかりますが、画面に「成長中」の画像が表示されません。

私は何を間違っていますか?Liferay 6.0.6 と Spring Portlet MVC でファイルを実際にストリーミングすることは可能ですか?

4

1 に答える 1

0

どこでこれをしているのですか?ポートレットの HTML をレンダリングする代わりにこれを行っているのではないかと心配しています (レンダリング フェーズなど)。通常、ポートレットのコンテンツは HTML ページに埋め込まれているため、(大まかに) サーブレットのように動作するリソース フェーズが必要です。

また、あなたが提供するコードは、あなたが尋ねる実際の質問と一致しません: コメント//read from input stream (file), write file to osを使用して、メモリ内に完全なコンテンツを持たないようにするために何をすべきかを尋ねます。

コメントにはメモリ内に何もないため、出力ストリームへの書き込み中に入力ファイルからの読み取りをループできます。根本的な質問は何ですか? ポータル環境でダウンロード ストリーミングを実装する際に問題が発生したり、ストリームへの書き込み中にファイルからの読み取りに問題 (メモリの使用量が多すぎるなど) がありますか?

編集:明確にしていただきありがとうございます。以前にストリームをフラッシュしようとしましたか? これは、いつでも実行できます。たとえば、ループごとに実行できます (ただし、少し多すぎるかもしれません)。また、ブラウザとファイル自体が期待どおりに処理する必要があることに注意してください。画像が「インクリメンタル」にエンコードされていない場合、ブラウザはそのように表示しない可能性があります。

巨大なファイルでもこれを試しましたか?ファイルが小さすぎてトリガーできないため、自動フラッシュがトリガーされない可能性があります...

filename*=UTF-8''また、それは奇妙に見えると思います。有効なエンコーディングかもしれませんが、これは見たことがありません

于 2012-07-25T06:52:23.360 に答える