Liferay Portlet and JSF : Redirect during Render Phase

Julien Lafont picture Julien Lafont · Jul 29, 2011 · Viewed 7.8k times · Source

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.

Answer

Olaf Kock picture Olaf Kock · Jul 30, 2011

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.