JSF Custom Validator: h:message is not being rendered
I have the following FacesValidator:
@RequestScoped
@FacesValidator("passwordValidator")
public class PasswordValidator implements Validator {
@PersistenceUnit(unitName = "TradeCenterPU")
private EntityManagerFactory emf;
@Override
public void validate(final FacesContext context, final UIComponent comp, final Object values) throws ValidatorException {
String password = (String)values;
System.out.println("passwordValidator():" + password);
EntityManager em = emf.createEntityManager();
Query q = em.createNamedQuery("user.findByUsername");
q.setParameter("username", context.getExternalContext().getRemoteUser());
User user = (User)q.getSingleResult();
String pwhash = DigestUtils.md5Hex(password + user.getSalt());
System.out.println("User: " + user.getUsername() + ", PwHash: " + pwhash + ", Password: " + user.getPassword());
if (!pwhash.equals(user.getPassword())) {
System.out.println(comp.getClientId(context) + ": Old password is wrong!");
FacesMessage msg = new FacesMessage(
FacesMessage.SEVERITY_ERROR,
"The old password was not entered correctly.",
""
);
context.addMessage(comp.getClientId(context), msg);
throw new ValidatorException(msg);
}
}
}
Wich gets used in the following way:
<h:form id="profileform" action="#{userController.updatePassword}">
<h:messages errorClass="error_message" globalOnly="true"/>
...
<h:outputLabel for="password" value="Old password:" />
<h:inputSecret id="password" name="password" label="Old password">
<f:validateLength minimum="8" maximum="15" />
<f:validator validatorId="passwordValidator"/>
</h:inputSecret>
<h:message for="password" errorClass="error_message"/>
...
</h:form>
The problem now is, that the message which the Validator generates is never displayed. I know it gets gene开发者_如何学运维rated, because in the Glassfish-Log I can see
profileform:password: Old password is wrong!
I can't see any error in this especially since the message for the f:validateLength
gets displayed if the password is to long or to short.
If I do
context.addMessage(null, msg);
instead of
context.addMessage(comp.getClientId(context), msg);
the Message is shown in the h:messages
component.
Has anyone an idea? Thanks in advance
You see nothing, because you've constructed the FacesMessage
with a summary and a detail. When the detail is not null
, then it will be displayed instead. Since you've set it with an empty string, you "see" an empty message. You basically need to set detail to null
to get the summary to display.
But this isn't exactly the way you're supposed to set a message on a validation error. You should just throw the ValidatorException
and JSF will add the in the ValidatorException
constructed message to the context itself based on the component's client ID.
So, you need to replace
FacesMessage msg = new FacesMessage(
FacesMessage.SEVERITY_ERROR,
"The old password was not entered correctly.",
""
);
context.addMessage(comp.getClientId(context), msg);
throw new ValidatorException(msg);
by
String msg = "The old password was not entered correctly.";
throw new ValidatorException(new FacesMessage(msg));
and it will work as you expect.
精彩评论