bean验证后,JSF 2枚举属性丢失

时间:2013-02-12 17:59:56

标签: jsf enums bean-validation

使用JSF2(MyFaces 2.1)和CDI(Weld)我使用一个带有枚举的selectOneMenu来有条件地渲染第二个selectOneMenu(代码中的 doublemenu )。表单中还有其他几个字段,使用bean验证进行验证。

问题:

如果在单击commandButton后出现验证错误并显示错误消息,则不会再出现doublemenu。似乎 bean.type =='double'不正确。但为什么? selectOneMenu本身会将选项 double 显示为所选项目。

@javax.inject.Named
@javax.enterprise.context.RequestScoped
public class Bean {

private enum MyEnum {
    Single, Double
}

private MyEnum type;

public MyEnum getType() {
    return type;
}

public void setType(MyEnum type) {
    this.type = type;
}

public MyEnum [] getTypes() {
    return MyEnum.values();
}


<h:form>
<h:selectOneMenu value="#{bean.type}">
  <f:selectItems value="#{bean.types}" />
  <f:ajax render="doublemenu" />
</h:selectOneMenu>

<h:panelGroup id="doublemenu">
  <h:panelGroup rendered="#{bean.type == 'double'}">
    <h:selectOneMenu ...>
    </h:selectOneMenu>
  </h:panelGroup>
</h:panelGroup>
<h:inputText id="VALIDATED"/>
<h:commandButtonaction="#{bean.save}"
</h:form>

BTW: bean.save 未执行

1 个答案:

答案 0 :(得分:4)

这是因为你的bean是请求作用域。请求范围的bean在每个请求结束时被包含,并在每个请求的开始时新创建。这也适用于同一视图上的单个ajax请求。

在收集提交的值(应用请求值阶段)期间,还会评估rendered属性。但是,在收集提交的值时,#{bean.type}显然尚未设置(在更新模型值阶段期间仍需根据收集的提交值进行设置) )。由于您的bean是请求作用域,它将返回默认值,而不是先前请求的提交值。

基本上有两种方法可以解决这个问题。

  1. 将bean放在更广泛的范围内。 JSF正是为了这个目的而提供@ViewScoped。这是当前的JSF 2.1版本,只与CDI不兼容。如果不能选择切换到JSF @ManagedBean,那么您需要MyFaces CODI将JSF @ViewScoped透明地连接到CDI,或者等待JSF 2.2获得CDI兼容{{} 1}}开箱即用。

  2. 检查请求参数而不是bean属性。

    @ViewScoped
  3. 请注意,这一切与枚举完全无关。使用例如,你会遇​​到完全相同的问题。一个<h:selectOneMenu binding="#{type}" ...> ... </h:selectOneMenu> <h:panelGroup rendered="#{param[type.clientId] == 'Double'}"> 。另请注意,我在代码示例中修正了拼写错误,枚举值String绝对与Double不一样。

    另见: