在没有显式转换的情况下,在 EL 中放入 viewScope 映射的值是否总是强制转换为 java.lang.String?

Is a value put to viewScope map in EL without explicit converting always cast to java.lang.String?

f:selectItem 中的值是整数 (Const.DB_NEW_DATASET),但 testlistener 的输出始终是 java.lang.String。这不是我所期望的。

xhtml

<f:metadata>
    <f:importConstants type="foo.bar.Const" />
</f:metadata>
<h:selectOneListbox value="#{viewScope.foo}">
    <f:selectItem
        itemValue="#{Const.DB_NEW_DATASET}"
        itemLabel="foo" />
    <f:selectItem
        itemValue="#{Const.DB_NEW_DATASET}"
        itemLabel="bar" />
    <f:ajax listener="#{myBean.testlistener}" />
</h:selectOneListbox>

豆子

@Named
@ViewScoped
public class MyBean implements Serializable {
    @Inject
    @ViewMap
    private Map<String, Object> viewMap;

    public void testlistener() {
        System.out.println(viewMap.get('foo').getClass());
    }
}


public class Const {
    public static final Integer DB_NEW_DATASET = -1;
}

Mojarra 2.3.9.SP01

它实际上根本不是“转换为 java.lang.String”。它只是 ServletRequest#getParameter() 的默认类型,然后 JSF 未对其进行转换。

这是因为 #{viewScope.foo} returns java.lang.ObjectValueExpression#getType() 因此 JSF 不会对任何已注册的 @FacesConverter(forClass) 执行任何自动转换。

您需要明确指定内置 javax.faces.Integer 转换器,它本质上是一个 @FacesConverter(forClass=java.lang.Integer)

<h:selectOneListbox ... converterId="javax.faces.Integer">

如果您使用的是例如#{bean.foo}private Integer foo,因为这样 ValueExpression#getType() 将 return java.lang.Integer 因此 JSF 可以找到内置转换器。

另请参阅:

  • Why does JSF put String values in a Map<..., Integer>? And how to work around it?
  • Conversion Error setting value for 'null Converter' - Why do I need a Converter in JSF?