最佳方法进行JSF表单验证

3
如果表单中有多个输入控件(每个输入控件都有不同的验证器,如必填、长度等),并且有一个命令按钮提交表单并调用操作方法。要求是-尽管输入控件的值都可以单独使用,但这些值的组合在表单提交后应该可以一起处理-我在哪里放置代码以一起验证它们?
1)我可以在命令按钮上添加自定义验证器,并一起验证组合吗?像validate(FacesContext arg0, UIComponent arg1, Object value),但即使如此,除了命令按钮/组件的值之外,我将没有其他输入控件的值,对吗?
2)我可以在操作方法中进行组合验证,并使用FacesMessage添加验证消息吗?
或者您建议采用其他方法?
感谢您的时间。
3个回答

5

第二点已经由Bozho回答。只需使用FacesContext#addMessage()。一个null客户端ID将使其落在<h:messages globalOnly =“true”>中。一个固定的客户端ID,如formId:inputId,将使其落在<h:message for =“inputId”>中。

第一点是可行的,您可以在验证器方法中使用UIViewRoot#findComponent()来获取其他组件:

UIInput otherInput = (UIInput) context.getViewRoot().findComponent("formId:otherInputId");
String value = (String) otherInput.getValue();

然而,您需要将f:validator放置在最后一个UIInput组件中。将其放置在UICommand组件(如按钮)中将不起作用。

诚然,硬编码客户端ID是讨厌的,但这是JSF中有点不灵活的验证机制的代价。


在第二种方法中添加消息后,如何停止执行? - gekrish

5
我刚刚看到您的帖子,因为我有同样的问题。
我读过的文章确认有四种验证类型用于以下目的:
1. 组件内置(订阅各个字段; required=true, LengthValidator等) 2. 在Backing Bean中的Action中添加" 应用验证 "(业务逻辑) 3. 自定义验证器(订阅各个字段) 4. Backing Bean 中的方法用作自定义验证器(订阅各个字段)。
关于 Validators:JSF 中的验证机制是设计用来验证单个组件。在想要将整个表单作为字段的逻辑分组进行验证时,最适合使用应用程序验证,因为在这一点上,各个字段的集合具有共同的业务含义。 (请参考链接:(查看S/O问题))
BalusC想出了一种将表单验证嵌入到附加到最后一个表单项的单个验证器中的方法(请参见S/O问题here和他网站上的另一个实例here),但它不一定是可扩展/可重用的,因为对表单ID的引用必须硬编码,而无法附加到validate()方法的签名中。如果您只使用表单一次,则可以摆脱它,但如果它多次弹出或者如果您以编程方式生成ID,则会卡住。
Seam的JSF实现部分有一个<s:validateForm />控件,可以将表单中其他地方的字段ID作为参数传递。不幸的是,似乎MyFaces/Mojara/Sun JSF实现中没有相应的功能,因为它不是标准的一部分。

3

我已经成功地使用了第二种方法:

FacesMessage facesMessage = 
      new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
FacesContext.getCurrentInstance().addMessage(null, facesMessage);

谢谢Bozho。我更喜欢使用第二种方法。 - gekrish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接