- - PR -
Tomcatフィルターを通して、動画・音楽ファイルをリクエストした時に例外が発生する
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-03-02 11:00
はじめまして。
現在、Tomcat認証フィルターを製造しているのですが、フィルターを通して動画・音楽 ファイルをダウンロード・ストリームしようとすると 「java.lang.IllegalStateException: レスポンスをコミットした後でフォワードできま せん」 という例外が発生してしまいます。 doFilterのみを実行する(リクエストをそのまま素通りさせる)フィルターを作成して 実験してみても同様の例外が発生してしまいます。 認識としては、1度のレスポンスで送信しきれない大きいサイズのファイルを要求した 場合、複数リクエストが発生してしまい、前回のリクエストをdoFilterしている間に 次のリクエストが来てしまい、上記例外が発生してしまっているという事でしょうか? 認識違いかもしれませんが、これを上手く切り抜ける方法はありませんでしょうか? ご存知の方いらっしゃいましたら、ご教授願います。 | ||||||||
|
投稿日時: 2007-03-02 11:20
レスポンスをコミット、というのはHTTPレスポンスちょっとでも返してしまったということです。
フォワードする前にバッファ以上にレスポンスに書き出したり、setError() とか flush() を呼び出したりすると発生します。 | ||||||||
|
投稿日時: 2007-03-02 11:21
HttpServletResponseからgetOutputStream()で取得したStreamに書き出しをはじめてから、
RequestDispatcher.forward()したりした場合に発生します。 意味はエラーメッセージ通り「レスポンスをコミットした後でフォワードできま せん」ですね。 Filterの扱い方か、Servetでのデータの書き出し方に誤りがあるのではないでしょうか。 どこかしらで、データを書き出してからforwordしているのでしょうから、 そうならないように設計を見直しましょう、としか言えませんね…。 | ||||||||
|
投稿日時: 2007-03-02 12:05
早速のご教授ありがとうございます。
インギさん バッファ以上にレスポンスを書き出したりというのは、バッファ以上のデータが書き込まれてしまった場合、データが漏れ出してレスポンスを知らない間に返してしまっているという可能性は考えられますか?
nagiseさん doFilterのみを実行する単純なフィルターで試してみても同様の結果でした。 となると、フィルター側ではなくフィルター対象サーブレット側が怪しそうですね。 ちなみに、例えば一度リクエストを返してしまった状態で、そのリクエストをキャンセルして、forwardしたりは出来ないものでしょうか? | ||||||||
|
投稿日時: 2007-03-02 12:10
>バッファ以上にレスポンスを書き出したりというのは、バッファ以上のデータが書き込まれてしまった場合、
>データが漏れ出してレスポンスを知らない間に返してしまってい 漏れ出す、というかそれが仕様です。 forwardするなら書き出さない、書き出すなら forward しない、のが基本です。 >ちなみに、例えば一度リクエストを返してしまった状態で、そのリクエストをキャンセルして、forwardしたり >は出来ないものでしょうか? 残念ですが、それが出来ない、というエラーメッセージです。 HTTP の仕様上無理です。 | ||||||||
|
投稿日時: 2007-03-02 12:16
一応、仕様のポインタを示しておきますね。
・JavaTM Servlet Specification Version 2.3 - SRV.5.1 Buffering P39 開発の際は仕様書を手元に置いておくことをオススメします。 http://jcp.org/aboutJava/communityprocess/final/jsr053/index.html | ||||||||
|
投稿日時: 2007-03-02 12:35
>ちなみに、例えば一度リクエストを返してしまった状態で、そのリクエストを
>キャンセルして、forwardしたりは出来ないものでしょうか? フォーワードを行うかを判断するタイミングを遅らせることができるのならば、 キャンセルという処理を行わなくても済んだりしないですかね。ある程度ストリーム に出力しなければ判断が付かないならば、判断するまではバッファに出力させて おいて、クライアントには何も返さない状態を作ってしまうとか。 | ||||||||
|
投稿日時: 2007-03-02 14:18
一度送出したHTTPパケットをキャンセルできるのであれば可能でしょう。 そう、インギさんもおっしゃるとおりHTTPの仕様上無理ですね。 擬似的にそれをやるのだとすれば、小僧氏がおっしゃるように バッファリングして実際には出力しないようにしておいて、 つまり、実際のHTTPレスポンスが飛ばないようにしておいて 差し替えるような工夫が必要ですね。原理的には。 |