2011-07-29 13 views
5

単純なHTTPリダイレクトを実装するのに問題があります。私はLiferayの6.0.6を使用LiferayポートレットとJSF:レンダリングフェーズ中にリダイレクト

、私たちのポートレットJSF2.0/PortletFacesでビルドされています。

ビューがロードされたときにリダイレクトを呼び出すといいです(アクションがトリガされたときではなく)。現在、私の関数はPreRenderViewリスナーによって呼び出されています。この機能で

<f:metadata> 
    <f:event listener="#{myControler.dispatch}" type="preRenderView" /> 
</f:metadata> 

、私は、権限を確認し、他のものを行うと、いくつかのケースでは、私は新しいページ(ない別のビュー)にユーザーをリダイレクトすることができます。

私はいくつかの方法を試みましたが、失敗しました。 は具体的に、私はこの方法がうまくいくことを考えた:

getFacesContext().getExternalContext().redirect(url); 
getFacesContext().responseComplete() 
// => Can only redirect during ACTION_PHASE 

このエラーは論理的であるが、リダイレクトへの解決策があります。

それはそうと呼ばれる別の関数、で実現することができ、私は(レンダリングフェーズの開始時に設定)HibernateのSessionを必要とする

は、この問題を解決するために、あなたのアイデアをお持ちですか?
ありがとう!

ps:<redirect />または?faces-redirectポートレットでは機能しません。

答えて

9

これは、デザインによってレンダリングフェーズでは実行できません。理由:

  • それはページがすでに表示される場合がありますので、あなたのポートレットが表示されているときに、ポートレットは、非同期的にレンダリングされている可能性があります
  • それは、ページの一部が既にように、クライアントに配信されている可能性がありますHTTPヘッダーはすでに送信されているため、レンダリングフェーズではデザインにアクセスできません。
  • 同じページにレンダリングされた2つのポートレットが転送先を決定すると、どのような結果が得られますか別のページ?誰が勝つだろうか?

ハック回避策はいくつかのJavaScriptリダイレクトレンダリングすることですが、これは相手の予想(プラス、ページの一部が既にユーザーがフォームに記入させ、レンダリングされる可能性がありますveeeery非ポータルのような缶めちゃくちゃですあなただけのJavaScriptのルーチンによってリダイレクトされる

問題を再考し、別の解決策を考え出すしてください - 。それは、ポータル環境でこれを行うことは本当に価値がある

+1

ありがとう、あなたの説明をありがとう。私は別の解決策を考え、必要に応じてポートレットのアーキテクチャをリファクタリングします。 –

+0

別の_hacky_回避策は、PortalUtil.getHttpServletResponseを使用して元のHTTP要求を検索し、そこでsendRedirectを使用することです。 –

+0

@TobiasLiefke * too hacky IMHO - レンダリング中に応答が既にコミットされている可能性があります。あるいは、ポートレットはAjaxを通じて配信されるかもしれません。ページ全体の一部としてではありません。それはうまくいくかもしれませんが、今でも動くかもしれないし、将来のアプリケーションサーバーのアップデートで中断するかもしれません... –

0

以下の方法を使用し、それは

public static void redirect(final String url) throws IOException { 

      final javax.portlet.PortletResponse portletResponse 
      = getPortletResponse(); 

      if (portletResponse instanceof ActionResponse) { 

       final javax.portlet.ActionResponse actionResponse 
       = (javax.portlet.ActionResponse) portletResponse; 

       actionResponse.sendRedirect(url); 

      } else if (portletResponse instanceof ResourceResponse) { 

       final FacesContext ctx = FacesContext.getCurrentInstance(); 
       if (ctx.getPartialViewContext().isPartialRequest()) { 

        final ResourceResponse portletResResp 
        = (ResourceResponse) portletResponse; 
        PartialResponseWriter pwriter; 
        final ResponseWriter writer = ctx.getResponseWriter(); 
        if (writer instanceof PartialResponseWriter) { 
         pwriter = (PartialResponseWriter) writer; 
        } else { 
         pwriter = ctx.getPartialViewContext() 
         .getPartialResponseWriter(); 
        } 
        portletResResp.setContentType(Constants.CONTENT_TYPE); 
        portletResResp.setCharacterEncoding(Constants.ENCODING_TYPE); 
        // addResponseHeader("Cache-Control", "no-cache"); 
        pwriter.startDocument(); 
        pwriter.redirect(url); 
        pwriter.endDocument(); 
        ctx.responseComplete(); 
       } else { 
        throw new UnsupportedEncodingException(
          "Can only redirect during RESOURCE_PHASE " 
          + "if a Partial-(JSF AJAX)-Request has " 
          + "been triggered"); 
       } 
      } else { 
       throw new UnsupportedEncodingException(
         "Can not redirect during the current phase: " 
         + portletResponse.getClass().getSimpleName()); 
      } 
     } 
に動作します。
+0

申し訳ありませんが、RenderPhase(portletResponse istanceof RenderResponseを使用して)中にリダイレクトしたいので、うまくいきません。だから私は "現在の段階の間にリダイレクトできません" –

0

私はこれを使用して私のために働きます:

public void preRenderView() throws IOException { 

     if (!checkUtente()) { 

       FacesContext fc = FacesContext.getCurrentInstance(); 

       NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler(); 

       navigationHandler.handleNavigation(fc, null, "errore.xhtml?faces-redirect=true"); 

       fc.renderResponse(); 
     } 

    } 
関連する問題