Java 嵌套JSF表达式字符串
我希望使用值表达式的动态参数来实现这一点:Java 嵌套JSF表达式字符串,java,jsf-2,el,Java,Jsf 2,El,我希望使用值表达式的动态参数来实现这一点: #{另一个bean[字段]} 其中字段是'user.name'或'location.address.zip'或 可能吗 请注意,这是一个简单的示例,我感兴趣的是ValueExpression而不是dataTable组件 更新 现在的问题是:如何取代标准BeanELResolver 查看洗脱液: ... composite.addRootELResolver(IMPLICIT_RESOLVER); composite.add(
#{另一个bean[字段]}
其中字段
是'user.name'
或'location.address.zip'
或
可能吗
请注意,这是一个简单的示例,我感兴趣的是ValueExpression
而不是dataTable
组件
更新
现在的问题是:如何取代标准BeanELResolver
查看洗脱液:
...
composite.addRootELResolver(IMPLICIT_RESOLVER);
composite.add(FLASH_RESOLVER);
composite.addPropertyELResolver(COMPOSITE_COMPONENT_ATTRIBUTES_EL_RESOLVER);
addELResolvers(composite, associate.getELResolversFromFacesConfig());
addVariableResolvers(composite, FacesCompositeELResolver.ELResolverChainType.Faces,
associate);
addPropertyResolvers(composite, associate);
composite.add(associate.getApplicationELResolvers());
composite.addRootELResolver(MANAGED_BEAN_RESOLVER);
composite.addPropertyELResolver(RESOURCE_RESOLVER);
composite.addPropertyELResolver(BUNDLE_RESOLVER);
...
但我还没有完全理解分解器链。。。所以我要去学习:)
更新2
此代码有效;)
这在默认情况下不受支持。您需要在此处自定义
ELResolver
。最简单的方法是扩展现有的
以下是一个启动示例:
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
中注册它:
com.example.ExtendedBeanELResolver
关于这个主题的工作非常有趣,但并不完整
若您在复合组件中传递值(在该组件中设置),它将不起作用
例如:
<composite:interface>
<composite:attribute name="value" type="java.lang.Boolean" required="true" />
</composite:interface>
<composite:implementation>
<h:inputText id="inputValue" value="#{cc.attrs.value}"
</h:inputText>
</composite:implementation>
(我添加了“设置值”部分)
现在它开始工作了。不要犹豫,给我你的反馈,因为这是我在这个网站上的第一篇帖子 不,我说的没错:
public List getSomeValue(){…}
这正是我想要解决的问题和其他一些小问题。谢谢@BalusC,你为我节省了很多时间,你应该得到我薪水的一部分;)但是,在faces config.xml
中声明它会覆盖默认的CompositeELResolver
。如何替换CompositeELResolver.elResolver中的标准BeanELResolver
?哎呀,我错了。它不会覆盖,但会在之前插入。请参阅问题更新。它到底给您造成了什么问题?更改应该是透明的,因为它始终委托super.causesPropertyNotFoundException
尝试读取bundles属性。但是,doc声明,由于此冲突解决程序处理任何类型的基本对象,因此应将其放置在复合冲突解决程序的末尾附近。否则,它将在随后出现的任何解析程序有机会测试它们是否也可以这样做之前,声明已解析属性。所以我解决了捕获PropertyNotFoundException
和设置context.setPropertyResolved(false)的问题代码>
<composite:interface>
<composite:attribute name="value" type="java.lang.Boolean" required="true" />
</composite:interface>
<composite:implementation>
<h:inputText id="inputValue" value="#{cc.attrs.value}"
</h:inputText>
</composite:implementation>
public class ExtendedBeanELResolver extends BeanELResolver {
private static final String PRIMEFACES_RESOURCE_PREFIX = "primefaces:";
private static final String RESOURCES_HANDLER = "class org.omnifaces.resourcehandler.GraphicResourceHandler";
private static final String PRIMEFACES_EXT_RESOURCES_HANDLER = "class org.primefaces.extensions.application.PrimeFacesExtensionsResourceHandler";
@Override
public Object getValue(ELContext context, Object base, Object property) {
if (property == null || base == null || base instanceof ResourceBundle || base instanceof Map || base instanceof Collection
|| property.toString().startsWith(PRIMEFACES_RESOURCE_PREFIX) || base.getClass().toString().equals(RESOURCES_HANDLER)
|| base.getClass().toString().equals(PRIMEFACES_EXT_RESOURCES_HANDLER)) {
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 {
Object v = super.getValue(context, base, property);
return v;
}
}
@Override
public void setValue(ELContext context, Object base, Object property, Object val) {
if (base != null && !(base instanceof ResourceBundle) && !(base instanceof Map) && !(base instanceof Collection))
super.setValue(context, base, property, val);
}
}