关于验证:验证 JSF 中的任意对象?

Validate arbitrary objects in JSF?

因此,您可以在绑定 bean 属性上使用 JSR-303 注释来验证输入:

1
2
3
4
5
6
7
8
9
10
11
class Ticket {
    @MinAge(18)
    Person person;
}

class Person {
    @Min(1) @Max(100)
    int age;
}

<p:inputText id="age" value="#{bean.ticket.person.age}" />

这里,Person.age 属性被验证(在 1..100 之间)没有问题。

问题是,我想验证外部实例 (person.age >= 18)。但是如何让属性 bean.ticket.person 被验证知道呢?

我想要类似的东西:

1
2
3
<p:inputText id="age" value="#{bean.ticket.person.age}">
    <f:validate value="#{bean.ticket.person}" />
</p:inputText>

或者:

1
2
3
<p:inputText id="age" value="#{bean.ticket.person.age}">
    <f:validator id="jsr303-validator" value="#{bean.ticket.person}" />
</p:inputText>

问题是,我不能将值传递给 <f:validator />。我想在验证过程中添加额外的属性,而不仅仅是页面上出现的输入。

附言这是一个简化的例子,真正的应用是:

1
2
3
4
5
...
<p:inputText id="principalLabel" value="${activeACL.principal.label}" readonly="true" />
<p:commandButton value="Choose..." onclick="choosePrincipalDialog.show()" />
...
<p:commandButton value="Save" action="${bean.saveACL}" oncomplete="editACLDialog.hide()" update="index" />

和 ACL_DTO 类型的 activeACL:

1
2
3
4
5
class ACL_DTO {
    ...
    @IdRequired
    Principal_DTO principal;
}

这里,choosePrincipalDialog\\的actionListener会隐式改变${activeACL.principal.id},最初是null。 IdRequired 是一个自定义约束,它约束对象的 id 成员属性不为 null 或 -1。

不过,我可以更改为在 id 属性上使用 @NotNull,并添加一个隐藏输入以启用对 id 的验证:

1
2
3
4
5
6
7
8
9
10
class Principal_DTO {
    ...
    @NotNull
    @Min(0)
    Long id;
}

...
<h:inputHidden id="principalId" value="${activeACL.principal.id}" />
<h:inputText id="principalLabel" ...

但是,这样我就不能再重复使用验证消息了。向用户提供诸如"此字符串不应为空"、"此值不应为-1"之类的消息似乎毫无意义。


首先,我认为您应该确保仅将 bean 用作您可以获取输入的地方。之后,您将值分配给模型。在我看来,bean 不应该直接用作模型,而应该用作 web-form-b??acking bean(每个 web 表单都有不同的 bean)。

其次,我同意您遇到过依赖其他数据来执行验证的情况(例如,如果用户选择美国作为国家,邮政编码等不应留空)。您可以在这里查看如何实现自定义注释:
使用 Hibernate Validator (JSR 303) 进行跨字段验证

如果您不使用 bean 验证,您始终可以实现自定义验证器类,甚至可以直接在 bean 中定义验证方法:http://docs.oracle.com/javaee/6/tutorial/doc/bnavb.html #bnave