2

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 generated, 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

1
  • Just wondering, are you using Seam 3? Since normally PhaseListeners are not injection targets and injecting the entity manager factory would not work. Commented May 29, 2011 at 18:15

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.