6

単純なHTTPリダイレクトを実装するのに問題があります。

私はLiferay6.0.6を使用していますが、ポートレット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セッション(レンダリングフェーズの開始時に設定)のみです。

この問題を解決するためのアイデアはありますか?
ありがとう!

ps:<redirect />または?faces-redirect、ポートレットを操作しません。

4

3 に答える 3

10

設計上、レンダリングフェーズでこれを行うことはできません。理由:

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

ハッキーな回避策は、JavaScriptリダイレクトをレンダリングすることですが、これはポータルに似ておらず、他の人の期待を台無しにする可能性があります(さらに、ページの一部がすでにレンダリングされている可能性があり、ユーザーがフォームに入力すると、 javascriptルーチン。

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

于 2011-07-30T09:08:24.050 に答える
1

私はこれを使用していますが、私にとってはうまくいきます:

    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(); 
        }

    }
于 2015-04-25T08:55:20.163 に答える
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());
            }
        }
于 2011-08-11T13:59:18.790 に答える