h:commandButton action redirect to context root, possible?

jsf, jsf-2

Solution

This isn't possible with (implicit) navigation. The `/` is unfortunately not a valid JSF view ID.

Use `ExternalContext#redirect()` instead. Replace

action="page.jspx?key=1&faces-redirect=true"

by

action="#{userActions.redirectToRootWithKey(1)}"

with

public void redirectToRootWithKey(int key) throws IOException {
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ec.redirect(ec.getRequestContextPath() + "?key=" + key);
}

Problem

Project context I've created from scratch an URL rewriting with two major component : ``` public class URLFilter implements Filter { ... } public class URLViewHandler extends GlobalResourcesViewHandler { ... } ``` The first class is used to forward clean URLs to the right view with an ID different for each page. The second class override the function `getActionURL()` so that `h:form` and ajax functionnalities continues to work. Theses classes translate like this : ``` Real URL Internal URL / <-> page.jspx?key=1 /contact <-> page.jspx?key=2 /projects/management <-> page.jspx?key=3 etc ``` Current solution My problem right now is for my user login and logout button : ``` <!-- Login button used if user is not logged, go to a secured page (which display error message). If he log with this button, the current page is reloaded and displayed properly. This button works perfectly --> <h:commandButton rendered="#{pageActions.item.isPrivate}" value="#{msg.button_connect}" actionListener="#{userActions.onButtonLoginClick}" /> <!-- Login button used anywhere on public pages that redirect to user home after login, works perfectly since I haven't changed to clear url. --> <h:commandButton rendered="#{not pageActions.item.isPrivate}" value="#{msg.button_connect}" actionListener="#{userActions.onButtonLoginClick}" action="userHome.jspx?faces-redirect=true" /> <!-- Logout button that works (it redirects at http://website.com/context-name/ but keep the ?key=1 at the end. --> <h:commandButton value="#{msg.button_disconnect}" actionListener="#{userActions.onButtonLogoutClick}" action="page.jspx?key=1&amp;faces-redirect=true" styleClass="button" style="margin-left: 5px;" /> ``` My whishes My question : Is there a better way to program the logout button since I need to redirect to context-root, currently I'm using the view name with the home page key but I would prefer 1. using a real path 2. not keep the ?key=1 at the url. Thank you! Final code Based on BalusC answer, here is my final code to share to others : ``` @ManagedBean @RequestScoped public class NavigationActions { public void redirectTo(String p_sPath) throws IOException { ExternalContext oContext = FacesContext.getCurrentInstance().getExternalContext(); oContext.redirect(oContext.getRequestContextPath() + p_sPath); } } <h:commandButton rendered="#{not pageActions.item.isPrivate}" value="#{msg.button_connect}" actionListener="#{userActions.onButtonLoginClick}" action="#{navigationActions.redirectTo(userSession.language.code eq 'fr' ? '/profil/accueil' : '/profile/home')}" /> ``` Since I don't need the key when I have the path, it is even more better, thank you again BalusC to put me on the right track! Sent a small donation :)

Original source