Liferay Portlet和JSF:在渲染阶段重定向

时间:2011-07-29 20:44:46

标签: redirect jsf-2 liferay portlet liferay-6

我在实现简单的HTTP重定向时遇到问题。

我使用Liferay 6.0.6,我们的 portlet 使用 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不适用于portlet。

3 个答案:

答案 0 :(得分:10)

您无法在渲染阶段进行设计。原因:

  • portlet可能是异步呈现的,因此在呈现portlet时可能已经显示了该页面
  • 页面的某些部分可能已经发送到客户端,因此HTTP标头已经发送 - 因此,按照设计,您无法在呈现阶段访问它们
  • 如果在同一页面上呈现的两个portlet决定他们想要转发到另一个页面,那么预期的结果是什么?谁会赢?

一个hacky解决方法是渲染一些javascript重定向,但这是非门户类的veeeery并且可以搞砸其他人的期望(此外,页面的某些部分可能已经呈现,导致用户只填写表单由你的javascript例程重定向。

请重新考虑问题并提出一个不同的解决方案 - 在门户环境中真的值得这样做。

答案 1 :(得分: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());
            }
        }

答案 2 :(得分: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(); 
        }

    }