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(在 Render Phase 开始时设置)

你有解决这个问题的想法吗?
谢谢!

ps:<redirect />或者?faces-redirect不使用portlet。

4

3 回答 3

10

您不能在设计的渲染阶段执行此操作。原因:

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

一个 hacky 的解决方法是呈现一些 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 回答