Search code examples
jsfjsf-2query-stringhttp-getmethod-invocation

Hit a bean method and redirect on a GET request


I'm using JSF 2 and PrimeFaces 2.1 on GlassFish.

I have a page that is intended to allow people to perform an action after following a callback URL (e.g. as link embedded in email or as callback URL parameter of some external authentication or payment service). In my case I need to reset the password. The callback URL has a token GET parameter like so:

http://example.com/app/resetPasswordForm.jsf?token=abc123

On page load of resetPasswordForm.jsf, I need to check if the token is valid and redirect to the main app screen if it's not valid.

My thinking is to have a bean method like:

public String resetPasswordHandler.showResetForm(String token) {
  if /* token is valid */ {
    return "resetPasswordForm.jsf";
  } else {
    return "main.jsf";
  }
}

But how would I cause that method to get hit on page load?

Not sure how to proceed -- suggestions are welcome.


Solution

  • Use <f:viewAction> to trigger a bean method before rendering of the view and simply return a navigation outcome (which will implicitly be treated as a redirect).

    E.g.

    <f:metadata>
        <f:viewParam name="token" value="#{authenticator.token}" />
        <f:viewAction action="#{authenticator.check}" />
    </f:metadata>
    

    with

    @ManagedBean
    @RequestScoped
    public class Authenticator {
    
        private String token;
    
        public String check() {
            return isValid(token) ? null : "main.jsf";
        }
    
        // Getter/setter.
    }
    

    If you're not on JSF 2.2 yet, then you can use the <f:event type="preRenderView"> workaround in combination with ExternalContext#redirect().

    <f:metadata>
        <f:viewParam name="token" value="#{authenticator.token}" />
        <f:event type="preRenderView" listener="#{authenticator.check}" />
    </f:metadata>
    

    with

    @ManagedBean
    @RequestScoped
    public class Authenticator {
    
        private String token;
    
        public void check() throws IOException {
            if (!isValid(token)) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("main.jsf");
            }
        }
    
        // Getter/setter.
    }
    

    See also: