在bean

时间:2017-01-03 20:31:23

标签: jsf jsf-2.2 classcastexception selectmanylistbox

我只是尝试了JSF,遇到了丑陋的ClassCastException

我有一个托管Bean(CustomerBean),它有一个POJO(Customer),用于存储用户数据。 POJO的一个属性是List<CathegoryType.Type> preferredCathegories(带有getter和setter)。 CathegoryType是一个模型类,它提供了导管(通过嵌套的enum Type)及其本地化名称(通过方法getCathegory(Type type))。

现在,我有一个JSF页面来输入一些用户数据(editCustomer.xhtml)。有一节可以选择首选的导管。选择导管的JSF代码如下所示:

<h:selectManyListbox 
        id="pcat"
        value="#{customerBean.customer.preferredCathegories}"
        styleClass="form-control">
    <f:selectItems 
            value="#{customerBean.cathegoryTypes}">
    </f:selectItems>
</h:selectManyListbox>

renderes组件如下所示: The renderes <code>selectMAnyListBox</code>

字段List<SelectItem> CustomerBeand.cathegoryTypes提供枚举文字到其名称new SelectItem(type, CathegoryType.getCathegory(type))的映射。现在有一个棘手的部分抛出ClassCastException(在我的理解中无缘无故!)

当我提交表单时,另一个JSF页面(showCustomer.xhtml)应该显示刚刚输入的用户数据。但是创建视图会因抛出以下ClassCastException而终止:

SCHWERWIEGEND: Servlet.service() for servlet [Faces Servlet] in context with path [/...] threw exception [java.lang.String cannot be cast to ...CathegoryType$Type] with root cause
java.lang.ClassCastException: java.lang.String cannot be cast to ...CathegoryType$Type
    at ...CustomerBean.getNamedPreferredCathegories(CustomerBean.java:247)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    ...

要显示所选的导管,showCustomer.xhtml会调用方法String CustomerBean.getNamedPreferredCathegories()

<h:outputText value="#{customerBean.namedPreferredCathegories}" />

此方法计算所选导管的String

def String getNamedPreferredCathegories() {
    val StringBuilder names = new StringBuilder
    val List<CathegoryType.Type> cathegories = customer.preferredCathegories
    val ListIterator<CathegoryType.Type> iter = cathegories.listIterator
    var boolean first = true
    while (iter.hasNext) {
        val CathegoryType.Type cat = iter.next
        val String name = cathegoryType.getCathegory(cat)
        if(first) first = false else names.append(', ')
        names.append(name)
    }
    return names.toString
}

我正在使用 Xtend 编程语言。它是一种JVM语言(编译为Java代码),因此与 Java类型系统完全兼容。我试图尽可能像Java一样编写这个方法,通常可以在一行中完成:

def String getNamedPreferredCathegories() {
    '''«FOR name : customer.preferredCathegories.map[cathegory] SEPARATOR ', '»«name»«ENDFOR»'''.toString
}

因为我对列表进行了任何迭代,所以抛出了ClassCastException ......但是正如我所看到的,我没有在我的代码中执行任何强制转换操作!那么异常来自哪里?

我在Tomcat 8.5.9上运行该项目。

修改 好的,生成的Xtend方法的Java方法如下:

public String getNamedPreferredCathegories() {
    final StringBuilder names = new StringBuilder();
    final List<CathegoryType.Type> cathegories = this.customer.getPreferredCathegories();
    final ListIterator<CathegoryType.Type> iter = cathegories.listIterator();
    boolean first = true;
    while (iter.hasNext()) {
        {
            final CathegoryType.Type cat = iter.next(); // Exception is thrown here!
            final String name = this.cathegoryType.getCathegory(cat);
            if (first) {
                first = false;
            } else {
                names.append(", ");
            }
            names.append(name);
        }
    }
    return names.toString();
}

在标记的行(final CathegoryType.Type cat = iter.next();)中抛出异常。另外,生成的相关Customer类的Java部分是:

public class Customer {

    private List<CathegoryType.Type> preferredCathegories;

    public List<CathegoryType.Type> getPreferredCathegories() {
        return this.preferredCathegories;
    }

    public void setPreferredCathegories(final List<CathegoryType.Type> preferredCathegories) {
        this.preferredCathegories = preferredCathegories;
    }
}

此外,我将查看可能讨论完全相同问题的链接问题。

0 个答案:

没有答案