在业务逻辑

时间:2015-11-10 16:08:13

标签: validation jsf jsf-2

验证时刻

Bean-Validation(通过Annotations验证,JSR 303)发生在JSF-Lifecycle的两个不同阶段:

PROCESS_VALIDATIONS - 阶段

  • 此阶段会调用@Size(max = 1024)@NotNull之类的简单验证程序。如果验证失败,则无法进一步获得一个阶段。

INVOKE_APPLICATION - 阶段

  • 在此阶段,第二次调用普通验证器。但是在这个阶段也会执行更复杂的验证器(参见Cross field validation - Post)。这些验证器无法提前运行,因为它们需要UPDATE_MODEL_VALUES - 阶段。

问题

在处理复杂表单时,有两个(或通过客户端验证)三个验证时刻是很烦人的。如果你添加

<context-param>
    <param-name>javax.faces.validator.DISABLE_DEFAULT_BEAN_VALIDATOR</param-name>
    <param-value>true</param-value>
</context-param>

web.xml,您可以跳过第一个验证阶段,以验证INVOKE_APPLICATION上的所有内容。但现在发生了一些可怕的事情:

JSF丢失了UI组件与facelets中引用的属性之间的连接。因此,如果<p:inputText value="#{myBean.entity.price}"/>的验证失败,则JSF不再知道对象price的属性entity位于@Named MyBean中。显示消息get,表示某些内容失败,但用户没有得到无效字段的提示。

途径

  • 第一种方法是实现一个调用visitTree的PhaseListener - Faces.getViewRoot()的方法。在给定的回调中,我迭代所有组件并尝试将所有验证消息映射到指定的UIComponent。 这种方法容易出错:我需要一个关于facelet中组件的id的约定。如果没有将字符串映射到组件ID的额外类,这也不适用于复合组件。太糟糕了!

  • 另一种方法是保存关系UIComponent&lt; - &gt;目标属性,值被分配。这发生在UPDATE_MODEL_VALUES中。所以我不必再猜测UIComponents了。

问题

你知道怎么做吗?我不知道,如果这种方法是现实的并且可以成功。

上一篇文章

我有一个运行webapp(JSF),Rest-API和(可能)JavaFX-app的应用程序。这就是为什么我更喜欢bean验证而不是基于视图的JSF验证来保持代码干燥的原因。

所以我跳过验证阶段并在updateModels-phase之后抛出验证异常。

到目前为止这种方法效果非常好,但在验证失败后我无法对输入字段进行染色。 (顺便说一句,“染上”正确的英语单词“让输入字段变红”?) 目前我使用约定来命名我的id和映射器,它将无效的对象字段映射到输入字段的id。

这有点乱,我想清理它。你有什么想法吗?

此致,Rokko

1 个答案:

答案 0 :(得分:0)

如果您不想使用客户端验证器,那么您可以添加支持bean的布尔值(每个字段1个),在验证期间设置它,并将其用于字段样式显示:< / p>

<h:outputLabel id="cardNumLabel" for="cardnum" value="*#{msg.cardNumLabel}"  
    styleClass="#{registrationBean.cardNumberValid ? '' : 'error'}" />
<h:inputText id="cardnum" 
    value="#{registrationBean.cardNumber}" label="#{msg.cardNumLabel}" size="35"
    styleClass="#{registrationBean.cardNumberValid ? '' : 'error'}" />

error样式在哪里

.error { color: #ed1c24; }