JSF Custom Validator:h:消息未呈现

set*_*ire 2 java validation jsf jsf-2

我有以下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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

以下列方式使用:

<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>
Run Code Online (Sandbox Code Playgroud)

现在的问题是,Validator生成的消息永远不会显示.我知道它会生成,因为在Glassfish-Log中我可以看到

profileform:password: Old password is wrong!
Run Code Online (Sandbox Code Playgroud)

我在这里看不到任何错误,特别是因为f:validateLength如果密码是长或短,则显示获取的消息.如果我做

context.addMessage(null, msg);
Run Code Online (Sandbox Code Playgroud)

代替

context.addMessage(comp.getClientId(context), msg);
Run Code Online (Sandbox Code Playgroud)

消息显示在h:messages组件中.有人有想法吗?提前致谢

Bal*_*usC 5

你什么也看不见,因为你已经构建了FacesMessage一个摘要细节.如果没有细节null,则会显示它.由于您使用空字符串设置它,因此您"看到"一条空消息.您基本上需要设置详细信息null以显示摘要.

但这并不是您应该在验证错误上设置消息的方式.您应该只是ValidatorException和JSF将添加了在ValidatorException构建的消息基于组件的客户端ID上下文本身.

所以,你需要更换

FacesMessage msg = new FacesMessage(
        FacesMessage.SEVERITY_ERROR,
        "The old password was not entered correctly.",
        ""
);
context.addMessage(comp.getClientId(context), msg);
throw new ValidatorException(msg);
Run Code Online (Sandbox Code Playgroud)

通过

String msg = "The old password was not entered correctly.";
throw new ValidatorException(new FacesMessage(msg));
Run Code Online (Sandbox Code Playgroud)

它会像你期望的那样工作.