JSF不支持交叉字段验证,有没有解决方法?
JSF 2.0只允许你验证一个字段的输入,比如检查是否有一定的长度。 它不允许你有一个表格,说:“输入城市和州,或只输入一个邮政编码”。
你怎么得到这个? 我只对涉及JSF验证阶段的答案感兴趣。 我不想把验证逻辑放在Managed Beans中。
我见过最简单的自定义方法是使用<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()
或者UIInput#getLocalValue()
如果UIInput
不是isValid()
)。
也可以看看:
- 多个字段的验证器(针对JSF 1.2)
或者,您可以使用第三方标签/组件。 例如RichFaces有一个<rich:graphValidator>
标签, Seam3为此拥有一个<s:validateForm>
,而OmniFaces有几个标准的<o:validateXxx>
组件,这些都在这里展示。 OmniFaces使用基于组件的方法,在UIComponent#processValidators()
完成这项工作。 它也允许以这种方式定制它,以便可以实现以上的功能:
<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
属性。
这里没有提到Apache ExtVal 。
这里有一些交叉验证(可能有用的其他验证):