【问题标题】:How to validate uniqueness in JSF and get a message to the user?如何验证 JSF 中的唯一性并向用户发送消息?
【发布时间】:2013-02-07 12:15:55
【问题描述】:

我需要检查应用程序中某个字段的唯一性。

我尝试使用 Hibernate @Unique 约束,但它显示堆栈跟踪,但用户表单中没有错误消息。

我的下一个解决方案是编写自定义验证器,但我认为有更好的解决方案。

在 JSF 中有更简单的方法吗?

(JSF 2.1 + RichFaces)

【问题讨论】:

  • 验证唯一性到底是什么?数据库中的值?还是内存数据存储?
  • 反对数据库中的值
  • 您几乎被自定义验证器所困。 This你可能会感兴趣

标签: java jsf validation unique-constraint


【解决方案1】:

我为我的基本实体的 JSF 2.1 唯一密钥验证破解了一个快速而肮脏的工作解决方案:

用法:

<p:inputText id="name" value="#{employeesController.currentEmployee.name}">
    <f:validator validatorId="uniqueColumnValidator" />
    <f:attribute name="currentEntity" value="#{employeesController.currentEmployee}" />
    <f:attribute name="uniqueColumn" value="name" />
</p:inputText>

验证者:

@RequestScoped
@FacesValidator("uniqueColumnValidator")
public class UniqueColumnValidator implements Validator, Serializable {

    @PersistenceContext
    protected EntityManager em;

    /**
     * generic unique constraint validator for AbstractBaseEntity entities<br />
     * requires the following additional attributes on the form element ("<f:attribute>"):<br />
     * - "currentEntity" the entity instance (used for getting the class and guid)<br />
     * - "uniqueColumn" the column where the new value will be checked for uniqueness
     */
    @Override
    public void validate(final FacesContext context, final UIComponent comp, final Object newValue) throws ValidatorException {

    AbstractBaseEntity currentEntity = (AbstractBaseEntity) comp.getAttributes().get("currentEntity");
    String uniqueColumn = (String) comp.getAttributes().get("uniqueColumn");

    boolean isValid = false;
    try {
        em.createQuery(
                "FROM " + currentEntity.getClass().getSimpleName()
                + " WHERE " + uniqueColumn + " = :value"
                + " AND guid <> :guid", currentEntity.getClass())
                .setParameter("value", value)
                .setParameter("guid", currentEntity.getGuid())
                .getSingleResult();
    } catch (NoResultException ex) {
        isValid = true; // good! no result means unique validation was OK!
    }

    if (!isValid) {
        FacesMessage msg = Messages.createError("must be unique", uniqueColumn);
        context.addMessage(comp.getClientId(context), msg);
        throw new ValidatorException(msg);
    }
    }
}

【讨论】:

    【解决方案2】:

    您可以通过 ajax 请求手动验证您的 bean。下面给出了手动验证的示例。

    ClassValidator<TestClass> classValidator = new ClassValidator<TestClass>(
                  TestClass.class );
    
    InvalidValue[] invalidValues = classValidator
            .getInvalidValues(testObject);
    
    for (InvalidValue invalidValue : invalidValues) {
           System. out .println( "Property Name: "
                   + invalidValue.getPropertyName() + " Message: "
                   + invalidValue.getMessage());
    }
    

    您可以使用&lt;a4j:support /&gt; 标签捕获 ajax 请求

    【讨论】:

    • 我没有在我的项目中使用 HibernateValidator。
    • &lt;a4j:support&gt; 适用于 RichFaces 3.3。由于 OP 使用 JSF 2.1,您应该使用 RichFaces 4 中的&lt;a4j:ajax&gt;
    【解决方案3】:

    您可以在textfield 上使用&lt;f:ajax /&gt;onblur 事件,并在您的支持bean 中验证不是model 的所有model 值。

    <h:message id="errorMessageTag" for="fieldId"/>
    <h:inputText id="fieldId" value="#{beanName.modelName.variableName}">
        <f:ajax event="blur" listener="#{beanName.property}" render="errorMessageTag" />
    </h:inputText>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-25
      • 1970-01-01
      相关资源
      最近更新 更多