在请求作用域的bean上可以使用required="true" 或 @NotNull注解吗?
我有一个表单,用于更新一个已存在实体的属性,其中有一个属性不能为null。我尝试在 <p:inputText /> 字段上使用 required="true",但如果把字段留空,在POST请求时,绑定到该页面的bean会在没有包含用于编辑实体主键的viewParam参数的情况下被重新构造,导致错误。我如果在绑定的bean的属性上指定 @NotNull 注解,结果也一样。到目前为止我找到的唯一解决办法是:要么不使用 required="true" 或 @NotNull,在我的bean的校验代码中对必填字段的空值进行检查(我在bean的 submit() 方法中调用它,发生错误时为下一个视图返回null),要么将bean从 RequestScoped改为ConversationScoped。不过这两种做法都需要在绑定的bean中编写大量额外的代码,我本来希望避免这种情况。以下是我的代码中相关的部分:
<f:metadata>
<f:viewParam name="termsid" value="#{ARTermsEditBean.termsID}" />
</f:metadata>
<body>
<f:event type="preRenderView" listener="#{ARTermsEditBean.initializeExisting}" />
<h:form id="artermsform">
<h:panelGrid columns="3" columnClasses="formLabel">
<h:outputLabel value="Terms" for="terms" />
<p:inputText id="terms" value="#{ARTermsEditBean.terms}"
required="true" maxlength="60" />
<p:message for="terms" />
<h:outputLabel value="Due Date Days" for="duedatedays" />
<p:inputText id="duedatedays" value="#{ARTermsEditBean.dueDateDays}"
maxlength="3" />
<p:message for="duedatedays" />
</h:panelGrid>
<p:commandButton value="Save" ajax="false"
action="#{ARTermsEditBean.submit}" />
</h:form>
</body>
编辑: 我还发现其他由RequestScoped bean支撑的页面,在把必填字段留空时并没有出现这个问题。在某些情况下,那些页面中的主键显示在只读字段中,与本页隐藏主键的情况不同,因此可以理解它们之所以能工作,因为主键值会随每次请求重新提交。但在其他情况下,即使主键显示在只读字段中,当必填字段留空时,主键也不会回传给bean。
解决方案
使用 @ViewScoped
这是JSF中“编辑”页面的标准架构解决方案。一个 @ViewScoped bean的生命周期在你与同一视图(页面)互动时保持一致。
当验证失败时,使用的是同一个bean实例来重新渲染页面。由于在初次加载时该实例中已经设置了 termsID,即使 f:viewParam 没有被重新处理,它仍然保留在那里。
变更:将 @RequestScoped 替换为 @ViewScoped(来自 javax.faces.view.ViewScoped 或 jakarta.faces.view.ViewScoped)。