2011-12-15 72 views
2

下面的Java代码允许访问来自faces上下文任何对象或变量的表达值:编程得到小面参数(变量)

ELContext elCtx = facesContext.getELContext(); 
ExpressionFactory exprFac = facesContext.getApplication().getExpressionFactory(); 
MyProperty myProperty = (MyProperty) exprFac.createValueExpression(elCtx, "#{somebean.someattr.someproperty}", MyProperty.class).getValue(elCtx); 

我使用的代码从我的自定义转换器内读取来自上下文附加转换参数。

如果在JSF上下文中将#{somebean}定义为正常的支持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'参数值?

回答

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); 
    } 
//... 
} 
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:参数”是一个facelet视图处理技术的一部分。 Facelets扩展了JSF。 两种技术在存储变量时都使用自己的上下文。 在Faces El Context旁边有一个Facelet El Context(FaceletContext)。

声明的方法评估两个上下文中的表达式。请注意,如果两个值在每个上下文中以相同名称存储,则这不起作用。

+0

谢谢!不幸的是,它似乎只适用于JSF 2.0。方法`getAttributes()`目前在我的项目中不可用。我们必须升级到最新的JSF版本。 [另请参阅Javadoc](http://docs.oracle.com/javaee/6/api/javax/faces/context/FacesContext.html#getAttributes()) – DRCB 2012-02-15 10:24:21

0

ui:param的映射不存储在上下文中,它位于各个ValueExpressionVariableMapper中。 所以如果你需要以编程方式创建ValueExpression,依靠另一ValueExpression的varMapper,你可以做这样的事情:

VariableMapper varMapper = new DefaultVariableMapper(); 
varMapper.setVariable(mappingName, component.getValueExpression(mappedAttributeName)); 
return new ValueExpressionImpl(expression, null, null, varMapper, expectedType);