我有两个简单的POJO:
class Person {
String name
Address address;
//and of course the getter/setter for the attributes
}
class Address {
String city;
//also getter/setter for this attribute
}
还有一个支持bean:
@ManagedBean
@RequestScoped
class PersonController {
private List persons;
private List<String> columns = Arrays.toList("name", "address.city");
//of course getter/setter
}
现在我想创建一个dataTable。
<p:dataTable var="person" value="#{personController.persons}" columnIndexVar="index">
<p:columns var="column" value="#{personController.columns}">
<h:outputText value="#{person[column]}"/>
<p:columms>
</p:dataTable>
当我执行此操作时,我得到一个ServletException:
Person类没有属性'address.city'。
但是如果尝试在p:columns:
中访问这样的属性城市<h:outputText value="#{person.address.city}"/>
一切都很好。
为什么我无法访问#{person['address.city']}
之类的嵌套属性?我如何在p:columns
内访问它?
答案 0 :(得分:9)
默认情况下,不支持括号表示法字符串表达式(如#{person['address.city']}
)中的嵌套bean属性。你基本上需要一个#{person['address']['city']}
。
您需要自定义ELResolver
。最简单的是扩展现有的BeanELResolver
。
这是一个启动示例:
public class ExtendedBeanELResolver extends BeanELResolver {
@Override
public Object getValue(ELContext context, Object base, Object property)
throws NullPointerException, PropertyNotFoundException, ELException
{
if (property == null || base == null || base instanceof ResourceBundle || base instanceof Map || base instanceof Collection) {
return null;
}
String propertyString = property.toString();
if (propertyString.contains(".")) {
Object value = base;
for (String propertyPart : propertyString.split("\\.")) {
value = super.getValue(context, value, propertyPart);
}
return value;
}
else {
return super.getValue(context, base, property);
}
}
}
要使其运行,请在faces-config.xml
:
<application>
<el-resolver>com.example.ExtendedBeanELResolver</el-resolver>
</application>
答案 1 :(得分:1)
除了@BalusC回答之外,我还要为PrimeResourceHandler添加一个检查。否则,在primefaces.css内的#{resource ...}的所有解析(如#{resource ['primefaces:spacer / dot_clear.gif']}都会失败,并且解析后的CSS文件的输出流会被破坏。
public class ExtendedBeanELResolver extends BeanELResolver {
private static final String PRIMEFACES_RESOURCE_PREFIX = "primefaces:";
@Override
public Object getValue(ELContext context, Object base, Object property) throws NullPointerException,
PropertyNotFoundException, ELException {
if (property == null || base == null || base instanceof ResourceBundle || base instanceof Map
|| base instanceof Collection || base instanceof PrimeResourceHandler) {
return null;
}
String propertyString = property.toString();
if (!propertyString.startsWith(PRIMEFACES_RESOURCE_PREFIX) && propertyString.contains(".")) {
Object value = base;
for (String propertyPart : propertyString.split("\\.")) {
value = super.getValue(context, value, propertyPart);
}
return value;
} else {
return super.getValue(context, base, property);
}
}
}