2011-12-15 3 views
2

次のJavaコードの式の値が顔コンテキストから任意のオブジェクトまたは変数にアクセスすることができます取得:は、プログラムのFaceletsパラメータ(変数)

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 

現在のJSFページに定義されたフェイスレットコンテキストと「ショートカット」パラメータ値を読むことを、アクセスする方法はありますか?

答えて

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> 

はその後、コンバータに私が入力子の1つとして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

私は同じ問題を抱えていたし、次のようなアプローチを選択しました: "UI:PARAM"

/** 
    * 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); 
    } 

は、技術を扱うにfaceletビューの一部です。 FaceletsはJSFを拡張します。 両方のテクノロジは、変数を格納するときに独自のコンテキストを使用します。 顔のElコンテキストの横にFacelet El Context(FaceletContext)があります。

上記のメソッドは両方のコンテキストで式を評価します。各コンテキストで同じ名前の下に2つの値が格納されている場合、これは機能しません。

+0

ありがとうございました!残念ながら、それはJSF 2.0でのみ動作するようです。メソッド 'getAttributes()'は私のプロジェクトでは使用できません。最新のJSFバージョンにアップグレードする必要があります。 [Javadocも参照](http://docs.oracle.com/javaee/6/api/javax/faces/context/FacesContext.html#getAttributes()) – DRCB

0

ui:paramのマッピングはコンテキストに格納されていませんが、ValueExpressionVariableMapperにあります。 あなたが別のValueExpressionのvarMapperに頼って、プログラム的ValueExpressionを作成する必要があるのであれば、あなたはこのような何かを行うことができます。

VariableMapper varMapper = new DefaultVariableMapper(); 
varMapper.setVariable(mappingName, component.getValueExpression(mappedAttributeName)); 
return new ValueExpressionImpl(expression, null, null, varMapper, expectedType); 
関連する問題