h:selectOneMenu绑定到int错误错误"验证错误:值无效"

bil*_*lly 3 jsf integer selectonemenu jsf-1.1

我坚持使用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>
Run Code Online (Sandbox Code Playgroud)

请求范围的bean:

public class Bean {
    private int num;

    public void setNum(Integer aNum) {
        num = aNum;
    }

    public Integer getNum() {
        return num;
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到验证错误:值无效,无法想象当我编写的代码很少而且不需要任何转换器时,我做错了什么.我错过了一些明显的东西,或者这是JSF RI 1.1_02中的一个错误?

我可以通过简单地更改支持bean中的属性类型来解决这个问题,String但是当我(自动)转换应该在那里时我必须这样做而感到沮丧.

Bal*_*usC 7

我花时间创建了一个JSF RI 1.1_02游乐场环境,我能够重现你的问题.检查源代码后,罪魁祸首似乎是该<f:selectItem>值永远不会转换为与提交值相同的类型.所以基本上它是将项目值String与提交的值Integer进行比较,并且这种比较永远不会返回true.

这是一个非常尴尬的错误,技术上只能通过替换UISelectOne组件来解决(UISelectMany顺便说一下暴露相同的bug).问题出在私有matchValue()方法中.自定义转换器(我最初想到的解决方案)不会以任何方式提供帮助,因为根本不会为该<f:selectItem>值调用它.

升级到Mojarra 1.2_15立即修复了问题.


更新:如果你真的,真的,无法升级,我找到了一个使用EL强制的解决方法:如果你引用EL中的值而不是静态字符串,那么它们被隐含地视为Long.如果您将属性类型更改IntegerLong,则它将在没有任何转换器的情况下工作.

<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>
Run Code Online (Sandbox Code Playgroud)

private Long num;
Run Code Online (Sandbox Code Playgroud)