- PR -

JSF レスポンスをコミットした後でフォワードできません

1
投稿者投稿内容
トリックスター
大ベテラン
会議室デビュー日: 2003/04/16
投稿数: 104
投稿日時: 2005-11-07 19:40
こんばんは。

TomcatのWebアプリがあります。
このアプリは最初にユーザ認証することにより、
利用できます。
しかし、URLを打つ事により直でJSFのページが
見えてしまいます。
そこで、Filterでチェックしようとしているの
ですが、
java.lang.IllegalStateException: レスポンスをコミットした後でフォワードできません
という例外が出てしまいます。

認証されていなければ、login.jsfへforward
するという簡単なFilterです。

いろいろ試しました。
・セッションからユーザーIDを取得
・クッキーからユーザーIDを取得
・ManagedBeanからユーザーIDを取得
いずれも、同例外となります。
回避策を教えてください。

web.xml
----
<filter>
<filter-name>authenticationFilter</filter-name>
<filter-class>〜.AuthenticationFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>authenticationFilter</filter-name>
<url-pattern>*.jsf</url-pattern>
</filter-mapping>
----

AuthenticationFilter.java
----
public class AuthenticationFilter implements Filter {

public void doFilter(ServletRequest request, ServletResponse response
, FilterChain chain) throws IOException, ServletException {

/* userIdがnullだったら未認証 */
HttpSession session = ((HttpServletRequest)request).getSession();
String userId = (String)session.getAttribute("userId");
// String userId = (String)FacesUtils.getBindObject("#{user.userId}");
if (userId == null || "".equals(userId)) {
RequestDispatcher dispacher = request.getRequestDispatcher("/login.jsf");
dispacher.forward(request, response);
}

chain.doFilter(request, response);
}

public void init(FilterConfig config) throws ServletException {
}

public void destroy() {
}

}
----
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2005-11-07 20:03
・フォワードではなくリダイレクトする
・フォワードした後returnしてdoFilterを終了する
のどちらかでできませんか?
トリックスター
大ベテラン
会議室デビュー日: 2003/04/16
投稿数: 104
投稿日時: 2005-11-08 12:16
ご教授ありがとうございました。

・フォワードではなくリダイレクトする

こちらは、同じ結果となりました。
「レスポンスをコミットした後でフォワードできません 」
リダイレクトなのに。

・フォワードした後returnしてdoFilterを終了する

こちらは、うまくいきました。
しかし、ここでreturnするということは、後続の
chain.doFilter(request, response);
が実行されないということですよね。
Filterは複数指定できますが、問題ないでしょうか。
今回の場合、"振り出しに戻る的に"フォワードして
しまうので、後続のFilterが実行されなくても問題
ないですが。
そもそも、例外が発生していた状況はどういった状況
だったのでしょうか?
ある.jsfがFilterで処理されフォワード、フォワード
された先.jsfがまたFilterで処理されフォワード。
ここで例外になるのでしょうか?

ちょっと疑問は残りますが、一応動くようにはなり
ました。ありがとうございました。

ちなみに、
・リダイレクトした後returnしてdoFilterを終了する
もやってみましたが、

HTTPステータス 404 - /login.jsf
The requested resource (/login.jsf) is not available.

というエラーになりました。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-11-08 16:36
レスポンスをコミット、というのはすでにレスポンスの一部がクライアントに送信されてしまっているということです。
JSFに限らずサーブレットではレスポンスコミット後にフォワードやリダイレクトはできません。

フォワードする前にバッファが溢れてしまったのではないでしょうか。
明示的に flush() を呼び出すようなことをしていなければ、あらかじめバッファを多めに設定することで回避できるかもしれません。
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2005-11-08 23:46
引用:

・フォワードではなくリダイレクトする

こちらは、同じ結果となりました。
「レスポンスをコミットした後でフォワードできません 」
リダイレクトなのに。


すいません。リダイレクトした場合もreturnが必要です。

引用:

・フォワードした後returnしてdoFilterを終了する

こちらは、うまくいきました。
しかし、ここでreturnするということは、後続の
chain.doFilter(request, response);
が実行されないということですよね。
Filterは複数指定できますが、問題ないでしょうか。


はい、doFilterが実行されるということは、最終的に(フィルタがなければ実行されるはずの)
JSPなりサーブレットなりが呼び出されてしまう、ということです。フォワードなりリダイレクト
なりした時点でレスポンスはコミットされていますので、その後にJSPやサーブレットが実行
されてしまうと結果としてエラーになります。

引用:

ちなみに、
・リダイレクトした後returnしてdoFilterを終了する
もやってみましたが、

HTTPステータス 404 - /login.jsf
The requested resource (/login.jsf) is not available.

というエラーになりました。


リダイレクトの場合、ブラウザからそのURLで参照できる必要があります。login.jsfがコンテナ
内部でしか参照できないパスであるということはないですか?
トリックスター
大ベテラン
会議室デビュー日: 2003/04/16
投稿数: 104
投稿日時: 2005-11-09 17:14
引用:

引用:

・フォワードした後returnしてdoFilterを終了する

こちらは、うまくいきました。
しかし、ここでreturnするということは、後続の
chain.doFilter(request, response);
が実行されないということですよね。
Filterは複数指定できますが、問題ないでしょうか。


はい、doFilterが実行されるということは、最終的に(フィルタがなければ実行されるはずの)
JSPなりサーブレットなりが呼び出されてしまう、ということです。フォワードなりリダイレクト
なりした時点でレスポンスはコミットされていますので、その後にJSPやサーブレットが実行
されてしまうと結果としてエラーになります。



理解できました。ご教授ありがとうございます。

引用:

引用:

ちなみに、
・リダイレクトした後returnしてdoFilterを終了する
もやってみましたが、

HTTPステータス 404 - /login.jsf
The requested resource (/login.jsf) is not available.

というエラーになりました。


リダイレクトの場合、ブラウザからそのURLで参照できる必要があります。login.jsfがコンテナ
内部でしか参照できないパスであるということはないですか?



ブラウザからそのURLで参照できます。
実体はlogin.jspだから、その辺が影響しているのかもしれません。
1

スキルアップ/キャリアアップ(JOB@IT)