Search code examples
validationjsf-2page-refreshpost-redirect-get

How to implement post-redirect-get when validation failed


I have a form in the view "createDbUser.xhtml" with some input texts and validations like this:

<h:form>
  <h:inputText id="user_name" value="#{dbUserManager.userName}" required="true" requiredMessage="User name is required." />
  <h:inputSecret id="password" value="#{dbUserManager.password}" required="true" requiredMessage="Password is required." />
  <h:commandButton id="create_user" value="Create user" action="#{dbUserManager.createUser()}" />
</h:form>

dbUserManger is a viewScoped managed bean with createUser() like this:

public String createUser()
{
  ...
  // here I do some checks and add the new user to database
  ...

  return "/restricted/createDbUser.xhtml?faces-redirect=true";
}

When I press the refresh button of my browser while some of the validations failed (e.g. I didn't enter password or username), I got "confirm form resubmission" instead of expected behaviour, i.e. reloading the page and clearing the inputs.

I've read about post-redirect-get pattern and that's why I added the return statement with "faces-redirect=true" parameter to the outcome of createuser().

I guess when validation failed we never get to the createuser() and consequently the return statement. And that's the cause of this problem. But I don't know how to solve it.

It would be very nice if some one help to solve the issue.

thanks


Solution

  • you are right:

    When validation errors are recognized on server side during JSF LifeCycles Validation Phase, your action method is never called (being in the invoke phase later on).

    What I would see as possible solutions: Try doing the validation client-side - for e.g. checking if login/pw exists, this could be achived via javascript triggered by h:commandButtons onclick-attribute. I'm not sure if you use any *Faces-framework above JSF2, but e.g. Richfaces4 also allows clientside validation without changing any code.

    Another possible solution might be to send the form via AJAX, changing

    <h:commandButton action="#{dbUserManager.createUser()}" />
    

    to something like

    <h:commandButton action="#{dbUserManager.createUser()}">
        <f:ajax execute="@form" render="@all" />
    </h:commandButton>
    

    Here you might need to figure out how to manage the redirect to another screen in case of a correct login.

    Hope, these ideas might push you further towards achieving your goals...