How would you compare two string for equality in a JSF Validator?
if (!settingsBean.getNewPassword().equals(settingsBean.getConfirmPassword())) {
save = false;
FacesUtils.addErrorMessage(null, "Password and Confirm Password are not same", null);
}
Use a normal Validator
on the second component and pass the value of the first component as attribute of the second component.
Thus, so
<h:inputSecret id="password" binding="#{passwordComponent}"
value="#{bean.password}"
required="true"
requiredMessage="Please enter password"
validatorMessage="Please enter at least 8 characters">
<f:validateLength minimum="8" />
</h:inputSecret>
<h:message for="password" />
<h:inputSecret id="confirmPassword"
required="#{not empty passwordComponent.value}"
requiredMessage="Please confirm password"
validatorMessage="Passwords are not equal">
<f:validator validatorId="validateEqual" />
<f:attribute name="otherValue" value="#{passwordComponent.value}" />
</h:inputSecret>
<h:message for="confirmPassword" />
(note that binding
on first component is exactly as-is; you shouldn't bind it to a bean property!)
with
@FacesValidator(value="validateEqual")
public class ValidateEqual implements Validator<Object> {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
Object otherValue = component.getAttributes().get("otherValue");
if (value == null || otherValue == null) {
return; // Let required="true" handle.
}
if (!value.equals(otherValue)) {
throw new ValidatorException(new FacesMessage("Values are not equal."));
}
}
}
If you happen to use the JSF utility library OmniFaces, then you can use <o:validateEqual>
for this. This exact case of "confirm password" is demonstrated on <o:validateEqual>
showcase.