简体   繁体   English

JSF 转换器在 PrimeFaces 表单验证后不起作用

[英]JSF converter does not work after validation in PrimeFaces form

I am working on an application using JSF 2.1 and PrimeFaces 3.2, server Tomcat 7. Right now, I am working on form to register new users.我正在使用 JSF 2.1 和 PrimeFaces 3.2,服务器 Tomcat 7 开发应用程序。现在,我正在处理注册新用户的表格。 The problem is in converter.问题出在转换器中。

I use few standard fields and two of them are passwords.我使用的标准字段很少,其中两个是密码。 I have custom data type for password, so I want to use converter to convert String data from field to Password variable in a bean.我有密码的自定义数据类型,所以我想使用转换器将字符串数据从字段转换为 bean 中的密码变量。 Primefaces forms use AJAX after submit, and there is probably the problem. Primefaces forms 提交后使用AJAX,应该是有问题。 If I fill in the form completely, without validation errors, everything works fine.如果我完整填写表格,没有验证错误,一切正常。 But if there is a validaton error and no converter error (I check for the password length in the converter), whole form stops working at all.但是,如果存在验证错误且没有转换器错误(我检查转换器中的密码长度),整个表单将完全停止工作。 I have to refresh page to have it working again.我必须刷新页面才能让它再次工作。

Here are some sources:以下是一些来源:

Password class:密码 class:

public class Password {

    public static final short MIN_LENGTH = 5;

    private String text;
    private String hash;

    public Password(String text) {
        this.text = text;
        this.hash = Hasher.sha512(text);
    }

    /**
     * Get password instance with known hash only
     * @param hash SHA-512 hash
     * @return Password instance
     */
    public static Password getFromHash(String hash) {
        Password password = new Password(null);
        password.hash = hash;
        return password;
    }



    @Override
    public int hashCode() {
        return hash.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Password other = (Password) obj;
        if ((this.hash == null) ? (other.hash != null) : !this.hash.equals(other.hash)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return hash;
    }

    /**
     * @return the text
     */
    public String getText() {
        return text;
    }
}

Password converter:密码转换器:

@FacesConverter(forClass = Password.class)
public class PasswordConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        String text = (String) value;

        if (text.length() >= Password.MIN_LENGTH) {
            return new Password(text);
        }

        FacesMessage msg = new FacesMessage(Texter.get("forms/forms", "shortPassword").replace("%limit%", String.valueOf(Password.MIN_LENGTH)));
        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
        throw new ConverterException(msg);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        try {
            Password password = (Password) value;
            return password.getText();
        } catch (Exception ex) {
            throw new ConverterException(ex);
        }
    }
}

The form in facelet: facelet 中的表单:

<h:form id="registration">
    <p:panelGrid columns="3">

        <h:outputLabel value="#{commonTxt.email}:" for="email" />
        <p:inputText id="email" value="#{userRegistrationForm.email}" required="true" requiredMessage="#{formsTxt.msgEmpty}">
            <f:validator validatorId="email" />

            <f:validator validatorId="unique" />
            <f:attribute name="entity" value="SystemUser" />
            <f:attribute name="field" value="email" />
            <f:attribute name="uniqueMessage" value="#{formsTxt.nonUniqueEmail}" />
        </p:inputText>
        <p:message for="email" />

        <h:outputLabel value="#{usersTxt.password}:" for="password" />
        <p:password id="password" value="#{userRegistrationForm.password}" binding="#{password}" autocomplete="off" feedback="true" weakLabel="#{formsTxt.passwordWeak}" goodLabel="#{formsTxt.passwordGood}" strongLabel="#{formsTxt.passwordStrong}" promptLabel="#{formsTxt.passwordPrompt}" />
        <p:message for="password" />

        <h:outputLabel value="#{usersTxt.passwordCheck}:" for="passwordCheck" />
        <p:password id="passwordCheck" value="#{userRegistrationForm.passwordCheck}" binding="#{passwordCheckInput}" autocomplete="off">
            <f:validator validatorId="match" />
            <f:attribute name="matchAgainst" value="#{password}" />
            <f:attribute name="matchMessage" value="#{formsTxt.passwordMismatch}" />
        </p:password>
        <p:message for="passwordCheck" />

        <p:column /><p:column /><p:column />

        <h:outputLabel value="#{usersTxt.name}:" for="name" />
        <p:inputText id="name" value="#{userRegistrationForm.name}" maxlength="255" required="true" requiredMessage="#{formsTxt.msgEmpty}" />
        <p:message for="name" />


        <f:facet name="footer">
            <p:commandButton value="#{usersTxt.register}" action="#{userRegistrationForm.register()}" update="registration" />
        </f:facet>
    </p:panelGrid>
</h:form>

I won't post code of the bean #{userRegistrationForm} , there are two Passwords properties with getters and setters.我不会发布 bean #{userRegistrationForm}的代码,有两个带有 getter 和 setter 的密码属性。

Any help leading to solution of my problem appreciated.任何有助于解决我的问题的帮助表示赞赏。 Thanks in advance.提前致谢。

Solved!解决了! I just used FacesContext.getCurrentInstance().isValidationFailed() to see if the validation failed or not.我刚刚使用FacesContext.getCurrentInstance().isValidationFailed()来查看验证是否失败。 In case of failure, the converter now returns null (the conversion won't be done), in other case the converter will return proper object. And the form works fine with the conversion working.万一失败,转换器现在返回 null(转换不会完成),在其他情况下转换器将返回正确的 object。并且该表格在转换工作中工作正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM