在请求作用域的bean上可以使用required="true" 或 @NotNull注解吗?

编程语言 2026-07-09

我有一个表单,用于更新一个已存在实体的属性,其中有一个属性不能为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.ViewScopedjakarta.faces.view.ViewScoped)。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章