Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Liferay Portlet and JSF : Redirect during Render Phase

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.

like image 952
Julien Lafont Avatar asked Jul 29 '11 20:07

Julien Lafont


2 Answers

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.

like image 71
Olaf Kock Avatar answered Nov 14 '22 13:11

Olaf Kock


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

    }
like image 23
Frizz1977 Avatar answered Nov 14 '22 13:11

Frizz1977