我一直在使用JSF RI 1.1_02并看到这个问题。
以下是我期望工作的Facelet代码:
<h:form>
<h:selectOneMenu value="#{bean.num}" converter="javax.faces.Integer">
<f:selectItem itemLabel="one" itemValue="1" />
<f:selectItem itemLabel="two" itemValue="2" />
<f:selectItem itemLabel="three" itemValue="3" />
</h:selectOneMenu>
<h:commandButton value="submit" />
<h:messages />
</h:form>
请求范围的bean:
public class Bean {
private int num;
public void setNum(Integer aNum) {
num = aNum;
}
public Integer getNum() {
return num;
}
}
我收到验证错误:值无效,无法想象当我写了这么少不需要任何转换器的代码时,我已经做错了什么。我是否遗漏了一些明显的东西,或者这是JSF RI 1.1_02中的一个错误?
我可以通过简单地将backingbean中的属性类型更改为String
来解决这个问题,但当(自动)转换应该存在时,我不得不这样做,这让我很沮丧。
我花时间创建了一个JSF RI 1.1_02游乐场环境,我能够重现您的问题。检查源代码后,罪魁祸首似乎是<f:selectItem>
值从未转换为与提交值相同的类型。因此,基本上它是将项目值String
与提交的值Integer
进行比较,而这种比较永远不会返回true
。
这是一个非常尴尬的错误,从技术上讲,只能通过替换UISelectOne
组件来解决(顺便说一下,UISelectMany
也暴露了同样的错误)。问题出在专用matchValue()
方法中。自定义转换器(我最初想到的解决方案)不会有任何帮助,因为它根本不会为<f:selectItem>
值调用。
升级到Mojarra 1.2_15立即解决了问题。
更新:如果您真的,真的无法升级,我找到了一个利用EL强制的解决方法:如果您引用EL中的值而不是静态字符串,那么它们将被隐式地视为Long
。如果将属性类型从Integer
更改为Long
,则它将在没有任何转换器的情况下工作。
<h:selectOneMenu value="#{bean.num}">
<f:selectItem itemLabel="one" itemValue="#{1}" />
<f:selectItem itemLabel="two" itemValue="#{2}" />
<f:selectItem itemLabel="three" itemValue="#{3}" />
</h:selectOneMenu>
带有
private Long num;