【问题标题】:How to bind List<Integer> values to selectManyListbox in JSF如何将 List<Integer> 值绑定到 JSF 中的 selectManyListbox
【发布时间】:2012-12-01 16:40:08
【问题描述】:

情况: 我有一个 JavaServer Faces 页面和一个会话范围的托管 bean,它有两个 ArrayList&lt;Integer&gt; 属性:一个用于保存可能值的列表,另一个用于保存选定值的列表。在 JSF 页面上有一个 &lt;h:selectManyListBox&gt; 组件绑定了这两个属性。

问题:提交表单后,选择的值会被转换成字符串(ArrayList类型的属性实际上包含几个字符串!);但是,当我使用转换器时,会收到如下错误消息:

验证错误:值无效

问题:如何将ArrayList&lt;Integer&gt; 属性正确绑定到&lt;h:selectManyListBox&gt; 组件?

感谢您对我的帮助。

具体代码

JSF 页面:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:body>
        <h:form>
            <h:selectManyListbox value="#{testBean.selection}">
                <f:selectItems value="#{testBean.list}"></f:selectItems>
            </h:selectManyListbox>
            <h:commandButton action="#{testBean.go}" value="go" />
            <ui:repeat value="#{testBean.selection}" var="i">
                #{i}: #{i.getClass()}
            </ui:repeat>
        </h:form>
    </h:body>
</html>

还有托管 bean:

import java.io.Serializable;
import java.util.ArrayList;

@javax.faces.bean.ManagedBean
@javax.enterprise.context.SessionScoped
public class TestBean implements Serializable
{
    private ArrayList<Integer> selection;
    private ArrayList<Integer> list;

    public ArrayList<Integer> getList()
    {
        if(list == null || list.isEmpty())
        {
            list = new ArrayList<Integer>();
            list.add(1);
            list.add(2);
            list.add(3);
        }
        return list;
    }

    public void setList(ArrayList<Integer> list)
    {
        this.list = list;
    }

    public ArrayList<Integer> getSelection()
    {
        return selection;
    }

    public void setSelection(ArrayList<Integer> selection)
    {
        this.selection = selection;
    }

    public String go()
    {
            // This throws an exception: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
            /*for (Integer i : selection)
            {
                System.out.println(i);
            }*/
        return null;
    }
}

【问题讨论】:

    标签: jsf-2 glassfish managed-bean


    【解决方案1】:

    List&lt;Integer&gt; 的泛型类型信息在运行时丢失,因此只看到 List 的 JSF/EL 无法识别泛型类型是 Integer 并假定它是默认的 String(如这是应用请求值阶段底层HttpServletRequest#getParameter() 调用的默认类型)。

    你需要任一明确指定Converter,你可以使用JSF内置IntegerConverter

    <h:selectManyListbox ... converter="javax.faces.Integer">
    

    只是改用Integer[],其类型信息在运行时是清楚的:

    private Integer[] selection;
    

    【讨论】:

    • 谢谢!该代码与添加的 IntegerConverter 一起正常工作。直到现在我才知道type erasure...
    • @BalusC,谢谢,这实际上是我的问题here 的答案。由于它以奇怪的方式呈现,因此弄清楚这可能是一件痛苦的事情。但是,我应该知道的更好......
    • 谢谢,这是一个必须小心的陷阱!刚刚遇到了 Set&lt;Long&gt; 的相同问题-在运行时出现奇怪的错误!
    • 用 1 天时间找出在 SelectManyMenu 中使用 List&lt;Long&gt; 对象时出现的 ClassCastException 问题。非常感谢@BalusC 拯救了疯狂
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-22
    • 2011-02-10
    • 2018-02-18
    • 2015-10-29
    • 1970-01-01
    相关资源
    最近更新 更多