但是,此验证不会与其他表单验证同时发生。
支持 bean 操作方法确实不打算执行输入验证。
有人有解决办法吗?
为工作使用正确的工具;使用普通的Validator。
@FacesValidator("dataRangeValidator")
public class DateRangeValidator implements Validator {
// ...
}
反过来,使用单个验证器验证多个输入值确实是另一回事。基本上,您应该将其他组件或其值获取/传递到validate() 方法实现中。在最简单的形式中,您可以为此使用<f:attribute>。假设您使用<p:calendar> 来选择日期,下面是一个具体的启动示例:
<p:calendar id="startDate" binding="#{startDateComponent}" value="#{bean.startDate}" pattern="MM/dd/yyyy" required="true" />
<p:calendar id="endDate" value="#{bean.endDate}" pattern="MM/dd/yyyy" required="true">
<f:validator validatorId="dateRangeValidator" />
<f:attribute name="startDateComponent" value="#{startDateComponent}" />
</p:calendar>
(注意 binding 属性,它使组件在 EL 范围内完全可用给定的变量名;还请注意,此示例是原样的,您绝对不应该将它绑定到 bean财产!)
dateRangeValidator 如下所示:
@FacesValidator("dateRangeValidator")
public class DateRangeValidator implements Validator {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (value == null) {
return; // Let required="true" handle.
}
UIInput startDateComponent = (UIInput) component.getAttributes().get("startDateComponent");
if (!startDateComponent.isValid()) {
return; // Already invalidated. Don't care about it then.
}
Date startDate = (Date) startDateComponent.getValue();
if (startDate == null) {
return; // Let required="true" handle.
}
Date endDate = (Date) value;
if (startDate.after(endDate)) {
startDateComponent.setValid(false);
throw new ValidatorException(new FacesMessage(
FacesMessage.SEVERITY_ERROR, "Start date may not be after end date.", null));
}
}
}
如果你碰巧使用了JSF utility library OmniFaces,那么你也可以只使用它的<o:validateOrder> component。无需自定义验证器即可实现如下要求:
<p:calendar id="startDate" value="#{bean.startDate}" pattern="MM/dd/yyyy" required="true" />
<p:calendar id="endDate" value="#{bean.endDate}" pattern="MM/dd/yyyy" required="true" />
<o:validateOrder components="startDate endDate" />
另见: