进行jsf表单验证的最佳方法

时间:2010-05-24 15:48:48

标签: jsf

如果表单中有很多输入控件(每个输入控件都有单独的验证器 - 如需要,长度等),有一个命令按钮,它提交表单并调用一个动作方法。要求是 - 虽然输入控制值是,例如,单独确定 - 这些值的组合应该可以在表单提交后一起处理它们 - 我在哪里放置代码来一起验证它们?

1)我可以为命令按钮添加自定义验证器并一起验证组合吗?像validate(FacesContext arg0, UIComponent arg1, Object value),但即便如此,除了命令按钮的/组件的值以外,我不会有其他输入控件的值吗?

2)我可以在操作方法中验证组合,并使用FacesMessage添加验证消息吗?

或者您是否建议采用其他方法?

感谢您的时间。

3 个答案:

答案 0 :(得分:4)

Bozho已经回答了第2点。只需使用FacesContext#addMessage()即可。 null客户端ID将使其登陆<h:messages globalOnly="true">。像formId:inputId这样的固定客户端ID会让它落在<h:message for="inputId">

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

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

但是,您需要将f:validator放在 last UIInput组件中。将其放在UICommand组件(如按钮)中将无效。

是的,硬编码客户端ID是令人讨厌的,但这是JSF中一点灵活的验证机制的回报。

答案 1 :(得分:4)

在遇到同样的问题之后,我刚刚登陆你的帖子。

我到目前为止所阅读的文章指出,出于以下目的,有四种类型的验证:

  1. 内置于组件中(订阅各个字段; required = true,LengthValidator等)
  2. '应用程序验证'已添加到Backing Bean中的操作(业务逻辑)
  3. 自定义验证器(订阅单个字段)
  4. Backing Bean中用作自定义验证器的方法(订阅各个字段)。
  5. 参考Validators:JSF中的验证机制旨在验证单个组件。 (See S/O Question here)

    如果您要将整个表单验证为字段的逻辑分组,则标准JSF / Apache MyFaces显示最适合的是作为应用程序验证,如在这一点上,一组个别领域具有集体商业意义。

    BalusC已经提出了一种将表单验证方式转换为附加到最后一个表单项的单个验证器的方法(再次参见S / O问题here和另一个工作示例在他的网站上here)但它不一定是可扩展/可重用的,因为对表单ID的引用必须是硬编码的,因为您不能附加到validate()方法的签名。如果你只使用一次表单,你就可以使用它,但是如果它弹出几次,或者如果你以编程方式生成你的ID,你就会被卡住。

    Seam的JSF实现部分有一个<s:validateForm />控件,可以将表单中其他位置的ID作为参数。不幸的是,似乎没有任何MyFaces / Mojara / Sun JSF实现具有等价物,因为它不是标准的一部分。

答案 2 :(得分:3)

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

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