我正在使用JSF 2(MyFaces 2.2.9)和Bean Validation(Hibernate Validator 5.2.2.Final)。
我在bean上使用@NotNull注释,该bean是我的托管bean的属性。
(ManagedBean类)
@ManagedBean
public class ConfiguracionesBean {
private Configuraciones configuraciones;
@PostConstruct
public void postConstruct() {
this.configuraciones = Configuraciones.find();
}
//getters/setters/unrelevant code
...
}
(Bean类)
public class Configuraciones {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@NotNull
private String name;
}
(。xhtml页面)
<h:outputLabel for="name">#{i18n['name']}</h:outputLabel>
<h:inputText id="name" label="#{i18n['name']}" value="#{configuracionesBean.configuraciones.name}" />
<h:message for="name" errorClass="error" warnClass="warn" infoClass="info"/>
第一次显示页面时,“名称”输入文本字段包含先前存储在我的数据库中的值(此处为正常值)。
如果我在html表单上删除了这个值,并且我提交了,那么@NotNull约束被触发,我得到一个错误(这里仍然正常)。
但是html页面上显示的inputText的值是托管bean初始化时的值。不是用户刚刚放置的“空”值(通过清空字段)。因此,用户会看到错误“字段不能为空”,但该字段实际上包含以前的值。
有没有办法防止这种情况发生?我希望输入为空,因为它是用户放置的。
我确切地知道我可以选择:
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
先谢谢你的回答。
注意:我真的很想坚持只用JSR 303完成的验证,因为我有一个统一的方法来处理约束。所以没有JSF验证器(我知道也可以这样做。)
亚历
答案 0 :(得分:1)
这是正常行为。验证在JSF的“流程验证阶段”中处理。此阶段在“更新模型值”阶段之前计算。这意味着如果验证失败,您的模型(Bean)将不会使用无效值进行更新。将跳过“过程验证阶段”之后的所有阶段,并将执行“渲染响应阶段”。结果是,当您的无效字段被重新呈现时,它仍将显示旧值,因为模型尚未更新。
在“渲染响应阶段”中,您现在可以使用&lt; h:messages&gt;显示错误消息。我能想到防止旧模型值显示的唯一方法是使用ajax-Element而不是在渲染响应阶段渲染输入元素,而只是渲染其错误消息。
所以在你的xhtml中:
<h:outputLabel for="name">#{i18n['name']}</h:outputLabel>
<h:inputText id="name" label="#{i18n['name']}" value="#{configuracionesBean.configuraciones.name}">
<f:ajax event="valueChange" render="errorBlock" />
</h:inputText>
<h:panelGroup id="errorBlock">
<h:message for="name" errorClass="error" warnClass="warn" infoClass="info"/>
</h:panelGroup>
以下链接可能会有所帮助
JSF生命周期说明:http://developersbook.com/jsf/images/JSF-Lifecycle.png
JSF生命周期:https://docs.oracle.com/javaee/1.4/tutorial/doc/JSFIntro10.html#wp122256