-1

次のJSFバッキングBeanメソッドがあり、条件に応じてリダイレクトを実行する必要があります。

public void navigationStatus() throws IOException {
    log(LogMessages.getLogString(user, currentDatasource, nomeClasse, "navigationStatus", "navigationStatus"), null);
    logger.debug("INSIDE  navigationStatus ");
    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();

    if (!isUserEnabled()) {
        log(LogMessages.getLogString(user, currentDatasource, nomeClasse, "navigationStatus", "Sessione utente SCADUTA"), null);
        logger.debug("Sessione utente SCADUTA");
        response.sendRedirect("error.jsp");         
    }
}

ただし、これはすべてのページで機能するわけではありません。一部のページでは機能しますが、他のページでは機能しません。これはどのように発生し、どうすれば解決できますか?

4

1 に答える 1

0

これは、次の条件下では間違いなく失敗します。

  1. 着信HTTPリクエストはajaxリクエストです。
  2. HTTP応答はすでにコミットされています。

それらを解決/回避するには、次のことを行う必要があります。

  1. JSFの内部から生のサーブレットAPIを取得する代わりに、標準のJSF APIメソッドを使用してリダイレクトを送信します。これにより、実行中のJSFコンテキストについて何も認識されなくなります。

    context.getExternalContext().redirect("error.jsp");
    

    次に、着信HTTPリクエストがajaxリクエストである場合、上記のアプローチは、JSFajaxエンジンによって期待される適切なXML応答を透過的に返します。

    将来的には、JSFバッキングBean内のパッケージから何かをインポートする必要があるときはいつでも、javax.servlet.*すぐにコーディングを停止して、考えていた仕事に標準のJSFの方法が本当にないかどうかを自問する必要があります。

  2. レンダリング応答フェーズの前にジョブを実行します。たとえば、コンストラクターまたは@PostConstructページの「半分」について初めて参照されるリクエスト/ビュースコープのバッキングBeanでこれを行う場合、リダイレクトを送信するには遅すぎる可能性があります。 HTTP応答はすでにクライアント側に送信されています。これはノーリターンのポイントでありIllegalStateException、サーバーログにすべてが表示されるだけです。

    これが実際に当てはまる場合は、を<f:event>リッスンしてジョブを呼び出す必要がありますpreRenderView

    <f:event type="preRenderView" listener="#{bean.navigationStatus}" />
    
于 2013-03-26T13:45:38.367 に答える