3

我坚持使用 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;
    }
}

我收到Validation Error: Value is not valid并且无法想象当我编写了这么少不需要任何转换器的代码时我做错了什么。我是否遗漏了一些明显的东西,或者这是 JSF RI 1.1_02 中的错误?

我可以通过简单地将支持 bean 中的属性类型更改为来解决这个问题,String但是当(自动)转换应该为我提供时,我不得不这样做而感到沮丧。

4

1 回答 1

7

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

这是一个非常尴尬的错误,在技术上只能通过替换UISelectOne组件来解决(UISelectMany顺便暴露了相同的错误)。问题出在私有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>

private Long num;
于 2012-07-30T20:00:52.803 回答