12

is there a build-in mechanism to conditionally redirect to another view? I want the user to be redirected from the login page to the "home page" if he/she is already logged in.

I already have two basic approaches, but for the first I have no idea how to achieve and the second is sort of a dirty workaround.

  1. Add <meta http-equiv="Refresh" content="0; URL=home.jsf" /> and let it be rendered conditionally (EL : #{login.loggedIn})
  2. Add a <h:panelGroup /> which will also be conditionally rendered, containing some JavaScript doing the redirect.

Is there a way to achieve 1 or even another, more elegant solution? :-)

Thanks

Kai
  • 207
  • 4
  • 10

2 Answers2

19

You could use <f:event type="preRenderView"> for this.

E.g.

<f:event type="preRenderView" listener="#{login.checkAlreadyLoggedin}" />

with

public void checkAlreadyLoggedin() throws IOException {
    if (isLoggedIn()) {
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        ec.redirect(ec.getRequestContextPath() + "/home.xhtml");
    }
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Perfect! Works like a charme, thanks. In the meantime I discovered and tried another approach: I implemented a filter that was exclusively registered for the log in page, but it failed as I could not manage to access the `@SessionScoped` `login` bean nor the `User` it manages. The session was empty...?! – Kai Dec 06 '11 at 12:37
  • The filter will only work for a JSF `@ManagedBean`, not for a CDI `@Named` bean. – BalusC Dec 06 '11 at 12:44
  • Why doesn't returning a String from the listener method of the `preRenderView` event like `return "home.xhtml?faces-redirect=true"` work (doesn't make a redirect)? – Tiny Apr 08 '14 at 22:03
  • 2
    @Tiny: because it's a listener method not an action method. Essentially, the listener method is being abused here. That's why JSF guys introduced `` in JSF 2.2, which should be the right tool for the job. – BalusC Apr 09 '14 at 05:43
0

The solution set out by @BalusC doesn't work in case the view 'home.xhtml' is not the default view of the JSF portlet. For those who need to redirect to a non-default view during the render phase, I suggest the solution set out within this entry. That is, within the preRenderView method do the following:

FacesContext fc = FacesContext.getCurrentInstance();
NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler();
navigationHandler.handleNavigation(fc, null, "/views/nonDefaultView.xhtml?faces-redirect=true");
fc.renderResponse();

Credits to @Frizz1977

Community
  • 1
  • 1
txapeldot
  • 71
  • 2
  • 10