到目前为止,我见过和使用的最简单的自定义方法是创建一个带有 <f:validator> 的 <h:inputHidden> 字段,其中您将所有涉及的组件引用为 <f:attribute>。如果在待验证组件之前声明它,则可以通过UIInput#getSubmittedValue()获取验证器内部提交的值。
例如
<h:form>
<h:inputHidden id="foo" value="true">
<f:validator validatorId="fooValidator" />
<f:attribute name="input1" value="#{input1}" />
<f:attribute name="input2" value="#{input2}" />
<f:attribute name="input3" value="#{input3}" />
</h:inputHidden>
<h:inputText binding="#{input1}" value="#{bean.input1}" />
<h:inputText binding="#{input2}" value="#{bean.input2}" />
<h:inputText binding="#{input3}" value="#{bean.input3}" />
<h:commandButton value="submit" action="#{bean.submit}" />
<h:message for="foo" />
</h:form>
(请注意隐藏输入上的value="true";实际值实际上并不重要,但请记住,验证器不一定会在它为空或为空时被触发,具体取决于 JSF版本和配置)
与
@FacesValidator(value="fooValidator")
public class FooValidator implements Validator {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
UIInput input1 = (UIInput) component.getAttributes().get("input1");
UIInput input2 = (UIInput) component.getAttributes().get("input2");
UIInput input3 = (UIInput) component.getAttributes().get("input3");
// ...
Object value1 = input1.getSubmittedValue();
Object value2 = input2.getSubmittedValue();
Object value3 = input3.getSubmittedValue();
// ...
}
}
如果在待验证组件之后声明<h:inputHidden>,那么所涉及组件的值已经被转换和验证,你应该通过UIInput#getValue()或者@改为 987654323@(如果 UIInput 不是 isValid())。
另见:
或者,您可以为此使用 3rd 方标签/组件。例如RichFaces 有一个<rich:graphValidator> 标签,Seam3 有一个<s:validateForm>,OmniFaces 有几个标准的<o:validateXxx> 组件,它们都展示了here。 OmniFaces 使用基于组件的方法,工作在UIComponent#processValidators() 中完成。它还允许customizing它以这样的方式实现上述目标:
<h:form>
<o:validateMultiple id="foo" components="input1 input2 input3" validator="#{fooValidator}" />
<h:inputText id="input1" value="#{bean.input1}" />
<h:inputText id="input2" value="#{bean.input2}" />
<h:inputText id="input3" value="#{bean.input3}" />
<h:commandButton value="submit" action="#{bean.submit}" />
<h:message for="foo" />
</h:form>
与
@ManagedBean
@RequestScoped
public class FooValidator implements MultiFieldValidator {
@Override
public boolean validateValues(FacesContext context, List<UIInput> components, List<Object> values) {
// ...
}
}
唯一的区别是它返回一个boolean,并且消息应该在<o:validateMultiple>中指定为message属性。