【发布时间】:2015-01-05 17:25:42
【问题描述】:
我有不同的对象,它们都实现了相同的接口。所有这些对象都需要由<p:selectCheckboxMenu/> 选择。这些对象的默认值和选定值放在同一个Map<?,?>中,很少有这样的Maps在另一个Map中组合在一起。听起来很复杂,但请看下面的代码,一切都会清楚。
当我选择一个对象时,转换器从 MyBean(CDI bean)中获取所有对象的列表,通过 uuid 所需对象查找并返回它,而不抛出任何异常。当我尝试使用选定的对象时,问题就开始了。比如里面的这行代码:
来自MyBean的onObjectChange()方法:
List<AllObjects> objects= objectContainer.getControllers().get("Object 1").get("selected");
抛出异常:
java.lang.ClassCastException: [Ljava.lang.Object; incompatible with java.util.List
确实,当我将鼠标悬停在 objectContainer 上时,我看到它包含 selected=[Ljava.lang.Object;@dba1b6e7} 类型的对象但是当我在 Eclipse 的表达式面板中评估同一行代码时,我得到了所需的值:MyObject1@d8f0f5f8
我一般不明白是否可以做我正在做的事情,即<p:selectCheckboxMenu/> 可以选择几个具有相同界面的不同对象。如果是的话,为什么我会有这个铸造问题?我的同事说这可能是我的converter 的问题,我倾向于同意她的观点,但不知道它是否正确,如果是,如何解决。
更新:看起来问题不在Converter 内部,但由于我通过Collection 动态收集选定值,作为<ui:param/> 的值。我将其传递为List<AllObjects>,然后将其返回为Object。然后我可以将其转换为Object[],然后使用自省将其中的每个对象转换为适当的对象,并且它可以工作。但是为什么它会改变初始对象呢?它不应该这样做。
提前谢谢你和我的代码:
这是一个界面:
public interfaces AllObjects{
public String getName();
}
有多个对象,MyObject,MyObject1,MyObject2,它们实现了上面的接口:
public MyObject implements AllObjects{
...
}
这是我的 bean 以及我的对象是如何初始化的:
public MyBean {
Map<String, Map<String,List<AllObjects>>> objectContainer = new LinkedHashMap<String, Map<String,List<AllObjects>>>();
public void init(){
Map<String,List<AllObjects>> nameValuesPairs1 = new LinkedHashMap<String,List<AllObjects>>();
List<AllObjects> allSelectedObjects1 = new ArrayList<AllObjects>();
List<AllObjects> allDefaultObjects1 = new ArrayList<AllObjects>();
nameValuesPairs.put("default",allDefaultObjects1);
nameValuesPairs.put("selected",allSelectedObjects1);
Map<String,List<AllObjects>> nameValuesPairs2 = new LinkedHashMap<String,List<AllObjects>>();
List<AllObjects> allSelectedObjects2 = new ArrayList<AllObjects>();
List<AllObjects> allDefaultObjects2 = new ArrayList<AllObjects>();
nameValuesPairs.put("default",allDefaultObjects2);
nameValuesPairs.put("selected",allSelectedObjects2);
objectContainer.put("Object 1", nameValuesPairs1);
objectContainer.put("Object 2", nameValuesPairs2);
}
public void onObjectChange(){
...
List<AllObjects> objects= objectContainer .getControllers().get("Object 1").get("selected"); //throws exception
...
}
}
我的 *.xhtml 页面:
<h:panelGroup id="object_panel">
<ui:repeat id="objects_id" var="object" value="#{myBean.objectContainer.entrySet().toArray()}">
<p:selectCheckboxMenu
value="#{object.value['selected']}" label="#{object.key}"
converter="#{myObjectConverter}"
filter="true"
filterMatchMode="startsWith"
panelStyle="width:250px">
<f:selectItems value="#{object.value['default']}" var="value" itemValue="#{value}" itemLabel="#{value.name}" />
<p:ajax event="change" process="@this @parent" listener="#{myBean.onObjectChange}"/>
</p:selectCheckboxMenu>
</ui:repeat>
</h:panelGroup>
和转换器:
public class ChartParameterConverter implements Converter, Serializable {
@Inject
private MyBean myBean;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException {
AllObjects result = null;
...
//here to result assigned MyObject1 or MyObject2 type depends on condition and it being returned
...
return result;
}
...
}
【问题讨论】: