如果我有一个托管bean,如下所示:
@ManagedBean
@RequestSchoped
public class Example {
private List<String> stringList;
private List<Long> longList;
// getters, setters, etc. down here
}
并有一个自定义组件接受List作为属性:
<?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:cc="http://java.sun.com/jsf/composite"
xmlns:h="http://java.sun.com/jsf/html">
<!-- INTERFACE -->
<cc:interface>
<cc:attribute name="aList" type="java.util.List" />
</cc:interface>
<cc:implementation>
<!-- code is in here -->
</cc:implementation>
</html>
我怎样才能确保这有效:
<myComp:previousComponent aList="#{example.stringList}" />
但这没有:
<myComp:previousComponent aList="#{example.longList}" />
换句话说,我想为cc:attribute
做的事情如下:
<cc:attribute name="aList" type="java.util.List<java.lang.String>" />
但是,正如我们所知,xhtml并不善待使用&gt;或者&lt;。另外,由于Generics仅在编译时进行检查,我不确定如何完成。有谁知道这是否可行?
答案 0 :(得分:3)
如果您是生成这些列表的人,那么以下内容可能是一个简单的解决方案:
interface StringList extends List<String> {}
class ArrayStringList extends ArrayList<String> implements StringList {}
虽然不太优雅。
我认为我们已经达到了Java语言的界限。我遇到了同样的问题,无法找到更好的解决方案......
答案 1 :(得分:3)
您可以使用#{item.class.name}
检查每个项目的类型。 Class#getName()
返回表示类型的String
。例如。 java.lang.String
或java.lang.Long
。您可以在rendered
属性中使用它。
添加一个额外的属性,表示完全限定的类名。
<my:comp list="#{bean.list}" type="java.lang.String" />
与
结合使用<cc:attribute name="list" type="java.util.List" required="true" />
<cc:attribute name="type" type="java.util.String" required="true" />
和cc:implementation
中的这个逻辑:
<ul>
<ui:repeat value="#{cc.attrs.list}" var="item">
<h:panelGroup rendered="#{item.class.name == cc.attrs.type}">
<li>#{item}</li>
</h:panelGroup>
</ui:repeat>
</ul>