Jsf 2 如果实体的所有字段都为空,如何跳过bean验证?
我有一个地址实体,如下所示:Jsf 2 如果实体的所有字段都为空,如何跳过bean验证?,jsf-2,bean-validation,omnifaces,Jsf 2,Bean Validation,Omnifaces,我有一个地址实体,如下所示: @Entity public class Address implements java.io.Serializable { @Id @GeneratedValue(strategy = IDENTITY) private Long id; @Size(max = 100) private String street; @Size(max = 15) private String nr; @Field
@Entity
public class Address implements java.io.Serializable {
@Id @GeneratedValue(strategy = IDENTITY)
private Long id;
@Size(max = 100)
private String street;
@Size(max = 15)
private String nr;
@Field
@Size(min = 1, max = 20) @NotBlank
private String city;
}
这是其他几个实体的一部分。对于一个这样的实体,地址是可选的。
我有一个视图,用户可以通过几个表单输入编辑整个实体,包括几个地址字段
为了能够编辑地址,我用空地址实体初始化父实体
现在的问题是:当所有地址字段都为空时,我不想在实体上保留地址。如果(并且仅当)Address
的所有字段都为空,我需要跳过实体的验证。我如何以最优雅的方式做到这一点
我目前正在做的是使用提交按钮的
跳过bean验证,如果地址为空,则将地址设置为null
。但这听起来像是一个彻底的黑客行为,因为它在所有情况下都会禁用所有验证。如何才能做得更好?多个字段的交叉验证可能是一个棘手的问题。但在这种情况下,首先困扰您的不是验证本身,而是在您持久化实体之前,在bean中的某些条件下取消某些实例的可能性
最直接的方法是在视图中将与地址
实体关联的所有字段标记为required=“false”
,而不关心正在填充的字段(或者忽略它,因为它是默认值),并对操作方法中的占位符进行所有检查和修改,就在调用EJB服务之前。像这样:
public String save() {
//do some checks
if((entity.getAddress().getStreet() == null) && ...) {
//assign address to null
entity.setAddress(null);
}
entityService.persist(entity);
return "success";
}
您只需在
(和
)的disabled
属性中使用EL即可。您可以使用EL检查这些字段是否已填充。您可以使用binding
属性引用EL中的组件。您可以通过检查与组件的客户端ID关联的请求参数的值来检查字段是否已填充
然后,要在{addressIsEmpty}
计算true
时禁用这些字段上的bean验证,更容易使用
而不是
,因为前者可用于包装多个输入组件
因此,总而言之,这应该做到:
<c:set var="addressIsEmpty" value="#{empty param[street.clientId] and empty param[nr.clientId] and empty param[city.clientId]}" />
<f:validateBean disabled="#{addressIsEmpty}">
<h:inputText binding="#{street}" value="#{bean.address.street}" />
<h:inputText binding="#{nr}" value="#{bean.address.nr}" />
<h:inputText binding="#{city}" value="#{bean.address.city}" />
</f:validateBean>
只有当您打算在每个输入或每个命令的基础上控制它时才更容易使用。问题是,默认情况下,JSF将执行Bean验证,即使字段是required=false
(它们在我的代码中)。如果验证失败,即使是完全合理的,也意味着我的save
永远不会被调用。是的,这是一个很好的观点!与往常一样,BalusC的回答让我们再次走上正确的轨道。嗯,尽管检查param
值效果很好,但我不得不使用id的字符串值(我控制命名容器和输入的id
s),使用clientId
在尝试计算EL时给了我一个NullPointerException。这可能是因为值位于条件呈现的弹出窗口中吗?当引用任何绑定时,我得到的参数键为null
。虽然这只适用于
或
,但可以在
中输出它。听起来像是视图构建与渲染时间的问题?