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

发布于 2024-11-27 04:37:50 字数 916 浏览 0 评论 0原文

我在实现简单的 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:?faces-redirect 不适用于 portlet。

I have a problem to implement a simple HTTP redirection.

I use Liferay 6.0.6, our portlets are build with JSF2.0 / PortletFaces.

I want to call a redirection when a view is loaded (and not when an action is triggered). Currently, my function is called by the PreRenderView listener.

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

In this function, i can check the permissions, do other stuff, and in some cases I want to redirect the user to a new page (not another view).

I tried several methods, unsuccessfully.
Specifically, I thought that this method would work :

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

This error is logical, but is there a solution to force the redirection.

It could be realized in another function, called otherwise, I only need the Hibernate Session (set at the beginning of the Render Phase)

Have you ideas to resolve this problem?
Thanks!

ps : <redirect /> or ?faces-redirect don't work with the portlets.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤星 2024-12-04 04:37:50

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

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

一个 hacky 的解决方法是渲染一些 javascript 重定向,但这非常不像门户,并且可能会扰乱其他人的期望(另外,页面的部分内容可能已经渲染,导致您的用户填写表单后只能被您的重定向) 。

请重新思考问题并提出不同的解决方案 - 在门户环境中这样做确实值得

You can't do this in the render phase by design. Reasons:

  • It's possible that portlets are rendered asynchronously, so the page might already be displayed when your portlet is being rendered
  • It's possible that parts of the page are already delivered to the client, so that the HTTP Headers are already sent - for this reason, by design you don't have access to them in the render phase
  • What would be the expected outcome if two portlets rendered on the same page would decide that they'd like to forwards to another page? Who would win?

A hacky workaround is to render some javascript redirect, but this is veeeery un-portal-like and can mess up other's expectations (plus, parts of the page might already be rendered, causing your users to fill a form only to be redirected by your javascript routine.

Please rethink the problem and come up with a different solution - it's really worth doing this in a portal environment.

荒人说梦 2024-12-04 04:37:50

我使用这个并且它对我有用:

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

    }

I use this and it works for me:

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

    }
感悟人生的甜 2024-12-04 04:37:50

使用下面的方法就可以了

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

Use the below method it will work

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());
            }
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文