如何在JSF中将List
问题内容:
情况:我有一个JavaServer Faces页面和一个会话范围的托管bean,它具有两个ArrayList<Integer>
属性:一个用于保存可能值的列表,另一个用于保存所选值的列表。在JSF页面上,有一个<h:selectManyListBox>
绑定了这两个属性的组件。
问题:提交表单后,选定的值将转换为字符串(ArrayList类型的属性实际上包含几个字符串!);但是,当我使用转换器时,出现如下错误消息:
验证错误:值无效
问题:如何将ArrayList<Integer>
属性<h:selectManyListBox>
正确绑定到组件?
谢谢您的帮助。
具体代码
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;
}
}
问题答案:
通用类型信息List<Integer>
在运行时会丢失,因此仅看到的JSF / ELList无法识别该通用类型Integer并将其假定String为默认类型(因为这是HttpServletRequest#getParameter()
应用请求值阶段中基础调用的默认类型)。
你需要要么显式地指定一个Converter,你可以使用JSF内置IntegerConverter
:
<h:selectManyListbox ... converter="javax.faces.Integer">
或仅使用它Integer[],其类型信息在运行时清楚地知道:
private Integer[] selection;