4
votes

I need your help to understand this better. This is my case. I have a custom validator for each of my input controls in the form. So when there is any validation error,I add a corresponding FacesMessage in the validate method. My understanding was that when there is any validation error - or when there are any FacesMessages added in the validate method of the Custom Validator, it would skip the INVOKE APPLICATION phase and would directly call the RENDER RESPONSE PHASE - showing the FacesMessage that was added in the PROCESS VALIDATION Phase - Is this correct?

The problem I'm facing is - I add a FacesMessage in the PROCESS VALIDATION Phase - because of a validation error - and I add a confirmation message for the action that was taken by the user in the INVOKE APPLICATION PHASE - Now both are shown in the page in the RENDER RESPONSE Phase ? - If my understanding is correct in the above question - is it the best practice to conditionally add a confirmation FacesMessage after confirming that there are no FacesMessages in the currect FacesContext ?

This is how the message is added :

FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR,Constants.invalidMessageDetail,null);
         FacesContext.getCurrentInstance().addMessage(null, facesMessage);
throw new ValidatorException(facesMessage);

This is how it is shown:

<h:messages errorClass="ErrorMsg" warnClass="WarningMsg" infoClass="InfoMsg" layout="table"  />

Appreciate your help.

1

1 Answers

7
votes

My understanding was that when there is any validation error - or when there are any FacesMessages added in the validate method of the Custom Validator, it would skip the INVOKE APPLICATION phase and would directly call the RENDER RESPONSE PHASE - showing the FacesMessage that was added in the PROCESS VALIDATION Phase - Is this correct?

Partly true. It will only skip the update model values and invoke application phases when a ValidatorException is been thrown, not when simply a FacesMessage is been added to the FacesContext.

If my understanding is correct in the above question - is it the best practice to conditionally add a confirmation FacesMessage after confirming that there are no FacesMessages in the currect FacesContext ?

You need to throw the ValidatorException as follows:

public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    if (value does not meet conditions) {
        throw new ValidatorException(new FacesMessage("value does not meet conditions"));
    }
}

Then it will skip the update model values and invoke application phases as desired. Please note that you don't need to manually add the faces message to the context. JSF will do it all by itself when it has caught a ValidatorException.