我无法在ViewHandler
内检索包含EL的属性。
作为一个最小的例子,这是我的ViewHandler。它只查找属性"attributeName"
并打印出其值。
public class MiniViewHandler extends ViewHandlerWrapper
{
private ViewHandler defaultViewHandler = null;
public MiniViewHandler()
{
}
public MiniViewHandler(ViewHandler defaultViewHandler)
{
super();
this.defaultViewHandler = defaultViewHandler;
}
@Override
public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException
{
viewToRender.visitTree(VisitContext.createVisitContext(context),
new VisitCallback()
{
@Override
public VisitResult visit(VisitContext context, UIComponent target)
{
if (target.getAttributes().containsKey("attributeName"))
{
System.out.println("Found it: " + target.getAttributes().get("attributeName"));
}
return VisitResult.ACCEPT;
}
}
);
defaultViewHandler.renderView(context, viewToRender);
}
@Override
public ViewHandler getWrapped()
{
return defaultViewHandler;
}
}
这是在faces-config.xml
中注册的。我正在打的xhtml:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<f:view>
<f:attribute name="attributeName" value="#{2 + 5}"/>
</f:view>
<f:view>
<f:attribute name="attributeName" value="2 + 5"/>
</f:view>
</h:body>
</html>
记录的输出显示仅拾取了非EL属性。
INFO [stdout] (http-/127.0.0.1:8080-1) Found it: 2 + 5
答案 0 :(得分:3)
错误在于:
if (target.getAttributes().containsKey("attributeName"))
您正在使用containsKey()
检查是否已指定该属性。但是,如果属性为ValueExpression
,则无法使用此功能。这是UIComponent#getAttributes()
javadoc的摘录,重点是:
的getAttributes
public abstract java.util.Map<java.lang.String,java.lang.Object> getAttributes()
返回一个变量
Map
,表示与UIComponent
相关联的属性(和属性,见下文),由属性名称(必须是String
)键入。返回的实现必须支持所有标准和可选的Map
方法,并支持以下附加要求:
Map
实现必须实现java.io.Serializable
接口。- 任何添加
null
键或值的尝试都必须抛出NullPointerException
。- 任何添加非
String
密钥的尝试都必须抛出ClassCastException
。- 如果指定为键的属性名称与此
UIComponent
实现类的属性匹配,则以下方法将具有特殊行为:
containsKey()
- 返回false
。get()
- 如果属性是可读的,则调用getter方法并返回返回的值(将原始值包装在相应的包装类中);否则抛出IllegalArgumentException
。put()
- 如果属性是可写的,则调用setter方法设置相应的值(在相应的包装类中展开原始值)。如果该属性不可写,或者尝试将基本类型的属性设置为null
,则抛出IllegalArgumentException
。remove()
- 抛出IllegalArgumentException
。
因此,它总是为false
返回containsKey
的组件属性(读取:组件&#39; s ValueExpression
s)。这是因为动态属性不存储在属性映射中,而是存储在组件实例中,通过UIComponent#setValueExpression()
调用。他们只在致电get()
时才解决。
你基本上需要改变错误的行,如下所示,这也适用于&#34;静态&#34;属性:
Object value = target.getAttributes().get("attributeName");
if (value != null) {
System.out.println("Found it: " + value);
}
如果您想检查该属性是否实际设置,即使它会评估null
value="#{bean.returnsNull}"
,那么您更愿意检查UIComponent#getValueExpression()
不会返回null
。
if (target.getValueExpression("attributeName") != null) {
System.out.println("Found it: " + target.getAttributes().get("attributeName"));
}
但这反过来又不适用于&#34;静态&#34;属性。如有必要,您可以根据具体的功能要求组合检查。