2012-03-02 56 views
1

評估包含由其他標記創建的var的EL表達式時遇到問題。屬性標記的JSF表達式評估

我有一個項目,我正在使用自定義驗證器。

public class MyValidator implements Validator, StateHolder

,我與它關聯的標籤類:

public class MyValidatorTag extends ValidatorTag

這個類允許屬性fieldName,用適當的tld文件標籤:

<tag> 
    <name>my-validator</name> 
    <tag-class>my.packaga.MyValidatorTag</tag-class> 
    <body-content>JSP</body-content> 
    <description>This is my validator</description> 
    <attribute> 
     <name>fieldName</name> 
     <required>true</required> 
     <rtexprvalue>true</rtexprvalue> 
     <type>java.lang.String</type> 
     <description>This is some field I need</description> 
    </attribute> 
</tag> 

到現在爲止還挺好。但是這個設置不允許使用JSF EL表達式來表示屬性值。 所以驗證器類(沒有吊牌類)我使用此代碼來評估屬性值:

public static String evaluateEl(String expression) { 
    String value = null; 
    if (expression == null) { 
     return ""; 
    } 
    if ((expression.indexOf("#{") != -1) 
     && (expression.indexOf("#{") < expression.indexOf('}'))) { 
     Object evaledValue = 
      FacesContext.getCurrentInstance().getApplication().createValueBinding(
       expression).getValue(FacesContext.getCurrentInstance()); 
     if (evaledValue != null) { 
      value = evaledValue.toString(); 
     } else { 
      value = null; 
     } 
    } else { 
     value = expression; 
    } 
    return value; 
} 

它僅限於字符串,它適用於大多數EL表達式。表達式Hello #{1 eq 2}將導致該屬性的值爲Hello false。 但有一種情況不適用。任何包含由另一個標記創建的var的表達式都不起作用。數據表,數據瀏覽器,特別是<f:loadBundle>,例如

<f:loadBundle basename="mypackage.message.ui-strings" var="msgs" />

後跟包含驗證器的輸入組件:

<cust:my-validator fieldName="#{msgs['myfield1.name']}"></cust:my-validator>

fieldName的計算結果爲使用上述表達式求值代碼空字符串。將其更改爲#{requestScope.msgs....不能解決問題。看看loadBundle實現,它添加了var msgs來請求範圍,所以我不明白爲什麼vars不適合我。請有人幫助我理解。

+0

您正在使用哪個jsp或ee版本? Jsp 2.1包含統一的el,可以簡化這一點。 – 2012-03-02 11:40:15

+0

版本1.2恐怕。 – 2012-03-02 11:55:03

回答

4

任何包含由另一個標記創建的var的表達式都不起作用。數據表,數據瀏覽器,特別是例如

標記處理程序等<f:xxx>,和一些<ui:xxx>(具有rendered屬性那些)期間JSF視圖生成時執行,當一個JSF UI組件樹是要生產。它們不是UI組件樹的一部分。他們已經完成了製作必要的JSF UI組件的工作。

<h:xxx>和一些<ui:xxx> UI組件(那些具有rendered屬性)被JSF視圖期間執行渲染時,當一個大的HTML字符串是要產生要被髮送到當前的HTTP請求的HTTP響應。

因此,它們不會同步運行。

有用於驗證幾種方法去解決這個問題的最終用戶,這一切都是在這個回答中列出:How to set converter properties for each row of a datatable?

對於開發者,還有另一種解決方案,讓驗證擴展UIComponentBase,而不是在執行任務processValidators()。父組件僅由UIComponent#getParent()提供,其提交的值可由UIInput#getSubmittedValue()提供。

+1

+1好解釋。 – 2012-03-02 13:05:49

+0

所以基本上你建議我把驗證器變成JSF組件?有趣的想法,但是我認爲它不會解決我的問題 - >進一步的調查顯示(但我不確定),在輸入字段的驗證步驟中,loadbundle標記根本沒有被調用。 – 2012-03-02 13:37:13