34

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が変更されないことです。ただし、私の場合faces-redirect=true、プレーンHTMLページのような非JSFページにリダイレクトしたい場合、追加するとエラーがスローされます。

そして別のオプションは、BalusCがJSF2.0リダイレクトエラーで提案したとおりです

4

1 に答える 1

83

まず、「リダイレクト」という用語は、Web開発の世界ではLocation、クライアントが新しいGETリクエストを送信する必要がある新しいURLを含むヘッダーのみを含む空のHTTP応答をクライアントに送信するアクションです。だから基本的に:

  • クライアントはHTTPリクエストをに送信しますsomepage.xhtml
  • Location: newpage.xhtmlサーバーはヘッダー付きのHTTP応答を送り返します
  • クライアントはHTTPリクエストをに送信しますnewpage.xhtml(これはブラウザのアドレスバーに反映されます!)
  • サーバーは、コンテンツを含むHTTP応答を送り返しますnewpage.xhtml

Webブラウザの組み込み/アドオン開発者ツールセットを使用して追跡できます。Chrome / IE9 / FirebugでF12を押し、[ネットワーク]セクションをチェックして確認します。

JSFナビゲーションハンドラーはリダイレクトを送信しません。代わりに、ターゲットページのコンテンツをHTTP応答として使用します。

  • クライアントはHTTPリクエストをに送信しますsomepage.xhtml
  • サーバーは、コンテンツを含むHTTP応答を送り返しますnewpage.xhtml

ただし、元のHTTPリクエストがであったためsomepage.xhtml、ブラウザのアドレスバーのURLは変更されません。基本的なサーブレットAPIに精通している場合は、これがと同じ効果があることを理解する必要がありますRequestDispatcher#forward()


HttpServletResponseJSFのフードの下から引っ張ってそれを呼び出すsendRedirect()ことが適切な使用法であるかどうかについては、いいえ、それは適切な使用法ではありません。サーバーログはsで乱雑になりますIllegalStateException。これは、この方法では、応答処理の制御をすでに引き継いだことを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");
}

try-catch(はい、それを回避する必要はありませんIOException。例外を通過させるだけthrowsで、servletcontainerがそれを処理します)

または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()

参照:

于 2012-06-30T20:36:21.183 に答える