开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜