以下java代码允许从faces上下文访问任何对象或变量:
ELContext elCtx = facesContext.getELContext();
ExpressionFactory exprFac = facesContext.getApplication().getExpressionFactory();
MyProperty myProperty = (MyProperty) exprFac.createValueExpression(elCtx, "#{somebean.someattr.someproperty}", MyProperty.class).getValue(elCtx);
我使用自定义转换器中的代码从上下文中读取其他转换参数。
如果#{somebean}
被定义为JSF上下文中的普通支持bean,则代码可以正常工作。
Facelets允许创建JSF表达式的“快捷方式”。例如:
<ui:param name="shortcut" value="#{somebean.someattr.someproperty}" />
<div>#{somebean.someattr.someproperty} equals #{shortcut}</div>
在这种情况下,#{somebean.someattr.someproperty}
和#{shortcut}
都具有相同的值。
但是,使用上面的java代码无法访问这些“快捷方式”名称。例如:
MyProperty myProperty1 = (MyProperty) exprFac.createValueExpression(elCtx, "#{somebean.someattr.someproperty}", MyProperty.class).getValue(elCtx);
// myProperty1 has expected value
MyProperty myProperty2 = (MyProperty) exprFac.createValueExpression(elCtx, "#{shortcut}", MyProperty.class).getValue(elCtx);
// myProperty2 is null
有没有办法访问facelets上下文并读取当前JSF页面上定义的'shortcut'参数值?
答案 0 :(得分:3)
我遇到了同样的问题并选择了以下方法:
/**
* Führt eine Expression im aktuellen Faces EL Context
* UND im Facelets El Context aus.
*
* @param facesContext
* @param expression
* @return object
*/
private static Object executeExpressionInUIContext (final FacesContext facesContext, final String expression) {
final ELContext elContext = facesContext.getELContext();
final Application application = facesContext.getApplication();
Object result = executeExpressionInElContext(application, elContext, expression);
if (null == result) {
FaceletContext faceletElContext = (FaceletContext) FacesContext.getCurrentInstance().getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
result = executeExpressionInElContext(application, faceletElContext, expression);
}
return result;
}
private static Object executeExpressionInElContext (Application application, ELContext elContext, String expression) {
ExpressionFactory expressionFactory = application.getExpressionFactory();
ValueExpression exp = expressionFactory.createValueExpression(elContext, expression, Object.class);
return exp.getValue(elContext);
}
“ui:param”是Facelet视图处理技术的一部分。 Facelets扩展了JSF。 这两种技术在存储变量时都使用自己的 Context 。 除了Faces El Context之外,还有一个Facelet El Context(FaceletContext)。
陈述的方法在两种情境中评估表达式。请注意,如果在每个上下文中以相同的名称存储两个值,则无法使用此功能。
答案 1 :(得分:1)
在我尝试访问它们的上下文中似乎不存在facelet快捷方式。
我做了以下解决方法:在放置了我的输入元素的JSF页面上,我添加了一个<f:param>
元素作为我的转换器输入的子元素。
<h:inputText id="myid" value="#{action.myinput}">
<f:converter converterId="myConverter" />
<f:param name="converterParameters" shortcut="#{somebean.someattr.someproperty}"/>
</h:inputText>
然后在转换器中,我能够找到UIParam
元素作为输入子节点之一并从中读取我的快捷方式。
public Object getAsObject(FacesContext context, UIComponent component, String value) {
MyProperty myProperty = null;
try {
for (final UIComponent child : component.getChildren()) {
if ("converterParameters".equals(child.getAttributes().get("name"))) {
final ELContext elCtx = context.getELContext();
myProperty = (MyProperty) child.getValueExpression("shortcut").getValue(elCtx);
break;
}
}
if (myProperty == null) {
throw new NullPointerException("My property is undefined.");
}
} catch (Exception e) {
LOG.error("Cannot convert " + value + ". Use <f:param name=\"converterParameters\" "
+ "shortcut=\"#{here.comes.shortcut}\"/> for your input element. ", e);
throw new ConverterException("Cannot initialize converter.", e);
}
//...
}
答案 2 :(得分:0)
ui:param
的映射不存储在上下文中,它位于每个VariableMapper
的{{1}}中。
因此,如果您需要以编程方式创建ValueExpression
,依赖另一个ValueExpression
的varMapper,您可以执行以下操作:
ValueExpression