JSFのナビゲーションの違いは何ですか
FacesContext context = FacesContext.getCurrentInstance();
context.getApplication().getNavigationHandler().handleNavigation(context, null, url);
そしてリダイレクト
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.sendRedirect(url);
そして、いつ何を使用するかを決定する方法は?
ナビゲーションの問題は、faces-redirect=true
がナビゲーションURLのクエリ文字列に追加されない限り、ページURLが変更されないことです。ただし、私の場合、プレーンHTMLページのような非JSFページにリダイレクトする場合、faces-redirect=true
を追加するとエラーがスローされます。
そして、別のオプションは JSF 2.0リダイレクトエラー でBalusCが提案したとおりです。
まず、「リダイレクト」という用語は、Web開発の世界では、クライアントに新しいGETを送信する必要がある新しいURLを含むLocation
ヘッダーのみを含む空のHTTP応答をクライアントに送信するアクションです。要求。だから基本的に:
somepage.xhtml
_に送信します。Location: newpage.xhtml
_ヘッダーでHTTP応答を送り返しますnewpage.xhtml
_に送信します(これはブラウザーのアドレスバーに反映されます!)newpage.xhtml
_のコンテンツでHTTP応答を送り返します。Webbrowserの組み込み/アドオン開発者ツールセットで追跡できます。 Chrome/IE9/FirebugでF12を押し、[ネットワーク]セクションで確認してください。
JSFナビゲーションハンドラーはリダイレクトを送信しません。代わりに、ターゲットページのコンテンツをHTTP応答として使用します。
somepage.xhtml
_に送信します。newpage.xhtml
_のコンテンツでHTTP応答を送り返します。ただし、元のHTTP要求は_somepage.xhtml
_であったため、ブラウザーのアドレスバーのURLは変更されません。 基本的なサーブレットAPI に精通している場合、これは RequestDispatcher#forward()
と同じ効果があることを理解する必要があります。
JSFフードの下からHttpServletResponse
をプルし、その上でsendRedirect()
を呼び出すことが適切な使用方法であるかどうかについては、いいえ、それは適切な使用法ではありません。サーバーログはIllegalStateException
sで乱雑になります。この方法では、応答処理の制御をすでに引き継いだことをJSFに伝えておらず、JSFはデフォルトの応答処理ジョブを行うべきではありません。実際には、後で FacesContext#responseComplete()
を実行する必要があります。
また、マネージドBeanのようなJSFアーティファクトの_javax.servlet.*
_パッケージから何かをインポートする必要があるときはいつでも、コードを書くのを絶対にやめ、本当に正しい方法で物事を行っているかどうかを自問してください。あなたが達成しようとしていることや、タスクが実際にJSFマネージドBeanに属している場合は、すでに「標準JSF方法」ではありません(つまり、単純な サーブレットフィルタ がより良い場所でした)。
JSFでリダイレクトを実行する適切な方法は、アクションの結果に_faces-redirect=true
_クエリ文字列を使用することです。
_public String submit() {
// ...
return "/newpage.xhtml?faces-redirect=true";
}
_
または、 ExternalContext#redirect()
を使用して、ajaxやprerenderリスナーメソッドなどのアクションメソッド内にいない場合:
_public void listener() throws IOException {
// ...
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath() + "/newpage.xhtml");
}
_
(はい、IOException
に_try-catch
_を付ける必要はありません。例外をthrows
に通すだけで、サーブレットコンテナはそれを処理する)
または、 NavigationHandler#handleNavigation()
を使用して、特定のケースで、XMLナビゲーションケースおよび/または組み込みリスナーでカスタムナビゲーションハンドラーを使用している場合:
_public void listener() {
// ...
FacesContext fc = FacesContext.getCurrentInstance();
NavigationHandler nh = fc.getApplication().getNavigationHandler();
nh.handleNavigation(fc, null, "/newpage.xhtml?faces-redirect=true");
}
_
「プレーンHTML」ファイルのナビゲーションハンドラーが失敗する理由については、ナビゲーションハンドラーはJSFビューのみを処理でき、他のファイルは処理できないためです。 ExternalContext#redirect()
を使用する必要があります。