EL表達(dá)式

2024-03-07 18:37 更新

Dorado提供了兩種EL表達(dá)式,靜態(tài)EL表達(dá)式和動態(tài)EL表達(dá)式,在實(shí)做HelloWorld的范例中我們已經(jīng)初步接觸了靜態(tài)EL表達(dá)式.

差別

靜態(tài)EL表達(dá)式:在創(chuàng)建目標(biāo)對象的過程中一次性的求值. 動態(tài)EL表達(dá)式:以動態(tài)代理的方式創(chuàng)建目標(biāo)對象,并在外界每一次讀取相應(yīng)屬性時(shí)都進(jìn)行求值。 舉例說明: 如我們設(shè)置button的caption為${util.getDate()}. 則我們用java訪問這個(gè)屬性的時(shí)候:

System.out.println(button.getCaption());
System.out.println(button.getCaption());
System.out.println(button.getCaption());

上面的輸出是一樣的。 而如果改為動態(tài)表達(dá)式$${util.getDate()}:

System.out.println(button.getCaption());
System.out.println(button.getCaption());
System.out.println(button.getCaption());

這個(gè)時(shí)候上面的每一個(gè)輸出都不一樣,在每一次讀取的時(shí)候都會運(yùn)算求值。

動態(tài)EL表達(dá)式通過動態(tài)代理實(shí)現(xiàn),使用的時(shí)候需要注意隱式對象的選擇,例如我們不能在JS端使用Java端的對象做動態(tài)EL表達(dá)式

隱式對象

Dorado共提供了14個(gè)隱式對象,我們不需要預(yù)先定義就可以直接使用這些隱式對象。 與線程無關(guān) 與線程有關(guān) 可擴(kuò)展 如有需要,開發(fā)人員可以自行擴(kuò)展出更多的隱式變量. 擴(kuò)展方法:自定義EL表達(dá)式的隱式變量(SEUG)

說明

因?yàn)?EL 標(biāo)識符是作為隱式對象或限制了作用域的變量(通過屬性來實(shí)現(xiàn))解析的,因此有必要將它們轉(zhuǎn)換成 Java 對象。EL 可以自動包裝和解包其相應(yīng)的 Java 類中的基本類型 (例如,可以在后臺將 int 強(qiáng)制轉(zhuǎn)換成 Integer 類,反之亦可),但大多數(shù)的標(biāo)識符將成為指向完整的 Java 對象的指針。結(jié)果是,對這些對象的特性或(在對象是數(shù)組和集合的情況下)對其元素的訪問通常是令人滿意的。就為了實(shí)現(xiàn)這種用途,EL 提供了兩種不同的存取器(點(diǎn)運(yùn)算符(.)和方括號運(yùn)算符([])),也支持通過 EL 操作特性和元素。 ? 點(diǎn)運(yùn)算符通常用于訪問對象的特性。例如,在表達(dá)式 ${user.firstName} 中,使用點(diǎn)運(yùn)算符來訪問 user 標(biāo)識符所引用對象的名為 firstName 的特性。EL 使用 Java bean 約定訪問對象特性,因此必須定義這個(gè)特性的 getter 方法(通常是名為 getFirstName() 的方法),以便表達(dá)式正確求值。當(dāng)被訪問的特性本身是對象時(shí),可以遞歸地應(yīng)用點(diǎn)運(yùn)算符。例如,如果我們虛構(gòu)的 user 對象有一個(gè)實(shí)現(xiàn)為 Java 對象的 address 特性,那么也可以用點(diǎn)運(yùn)算符來訪問這個(gè)對象的特性。例如,表達(dá)式 ${user.address.city} 將會返回這個(gè)地址對象嵌套的 city 特性。? 方括號運(yùn)算符用來檢索數(shù)組和集合的元素。在數(shù)組和有序集合(也即,實(shí)現(xiàn)了 java.util.List 接口的集合)的情況下,把要檢索的元素的下標(biāo)放在方括號中。例如,表達(dá)式${urls[3]?} 返回 urls 標(biāo)識符所引用的數(shù)組或集合的第四個(gè)元素(和 Java 語言以及 JavaScript 中一樣,EL 中的下標(biāo)是從零開始的)。對于實(shí)現(xiàn) java.util.Map 接口的集合,方括號運(yùn)算符使用關(guān)聯(lián)的鍵查找存儲在映射中的值。在方括號中指定鍵,并將相應(yīng)的值作為表達(dá)式的值返回。例如,表達(dá)式 ${commands["dir"]} 返回與 commands 標(biāo)識符所引用的 Map 中的 "dir" 鍵相關(guān)聯(lián)的值。對于上述兩種情況,都可允許表達(dá)式出現(xiàn)在方括號中。對嵌套表達(dá)式求值的結(jié)果將被作為下標(biāo)或鍵,用來檢索集合或數(shù)組的適當(dāng)元素。和點(diǎn)運(yùn)算符一樣,方括號運(yùn)算符也可以遞歸應(yīng)用。這使得 EL 能夠從多維數(shù)組、嵌套集合或兩者的任意組合中檢索元素。此外,點(diǎn)運(yùn)算符和方括號運(yùn)算符還可以互操作。例如,如果數(shù)組的元素本身是對象,則可以使用方括號運(yùn)算符來檢索該數(shù)組的元素,并結(jié)合點(diǎn)運(yùn)算符來檢索該元素的一個(gè)特性(例如 ${urls[3].protocol})。 假定 EL 充當(dāng)指定動態(tài)屬性值的簡化語言,EL 存取器有一個(gè)有趣的功能(與 Java 語言的存取器不同),那就是它們在應(yīng)用于 null 時(shí)不拋出異常。如果應(yīng)用 EL 存取器的對象(例如,${foo.bar} 和 ${foo["bar"]} 中的 foo 標(biāo)識符)是 null,那么應(yīng)用存取器的結(jié)果也是 null。事實(shí)證明,在大多數(shù)情況下,這是一個(gè)相當(dāng)有用的行為,不久您就會了解這一點(diǎn)。 最后,點(diǎn)運(yùn)算符和方括號運(yùn)算符可能實(shí)現(xiàn)某種程度的互換。例如,也可以使用 ${user["firstName"]} 來檢索 user 對象的 firstName 特性,正如可以用 $\commands.dir} 獲取與 commands 映射中的 "dir" 鍵相關(guān)聯(lián)的值一樣。

基本語法

EL 還可以通過使用標(biāo)識符和存取器,遍歷包含應(yīng)用程序數(shù)據(jù)(通過限制了作用域的變量公開)或關(guān)于環(huán)境的信息(通過 EL 隱式對象)的對象層次結(jié)構(gòu)。但是,只是訪問這些數(shù)據(jù) ,通常不足以實(shí)現(xiàn)許多 JSP 應(yīng)用程序所需的表示邏輯。 最終,EL 還包括了幾個(gè)用來操作和比較 EL 表達(dá)式所訪問數(shù)據(jù)的運(yùn)算符。

最后一種 EL 運(yùn)算符是 empty,它對于驗(yàn)證數(shù)據(jù)特別有用。empty 運(yùn)算符采用單個(gè)表達(dá)式作為其變量(也即,${empty input}),并返回一個(gè)布爾值,該布爾值表示對表達(dá)式求值 的結(jié)果是不是"空"值。求值結(jié)果為 null 的表達(dá)式被認(rèn)為是空,即無元素的集合或數(shù)組。如果參數(shù)是對長度為零的 String 求值所得的結(jié)果,則 empty 運(yùn)算符也將返回 true。 EL 運(yùn)算符優(yōu)先級(自頂?shù)降?,從左到右?/strong> 范例 文字 在 EL 表達(dá)式中,數(shù)字、字符串、布爾值和 null 都可以被指定為文字值。字符串可以用單引號或雙引號定界。布爾值被指定為 true 和 false。

特殊EL隱式變量

在使用Dorado EL表達(dá)式的時(shí)候,我們還需要掌握幾個(gè)特殊的EL隱式變量,如:$${this}或$${this.foo}.雖然寫法上像動態(tài)EL表達(dá)式,但其實(shí)際運(yùn)行的機(jī)制與一般EL表達(dá)式并不一樣,注意要點(diǎn): 此種隱式變量通常只用在DataType的Reference屬性中。this表示當(dāng)前正在處理的數(shù)據(jù)實(shí)體對象,即系統(tǒng)正在嘗試獲取該數(shù)據(jù)實(shí)體對象的Reference屬性的值。此種EL表達(dá)式的實(shí)際求值范圍是在Client端的JavaScript環(huán)境中。 Reference使用圖例:![] 關(guān)于這幾個(gè)EL表達(dá)式的實(shí)際用法我們將會在后面Reference的使用中用實(shí)例闡述

自定義EL表達(dá)式的隱式變量(SEUG)

Dorado中EL表達(dá)式的隱式變變量是由隱式變量初始化器實(shí)現(xiàn)初始化的。 一個(gè)典型的初始化器的格式如下:

public class XXXVarsInitializer implements ContextVarsInitializer {
    private static final Log logger = LogFactory.getLog(XXXInitializer.class);

 
    public void
    (Map<String, Object> vars) {
        vars.put("test", new MyExpressionBean());
    }
}

其中vars中包含的key即EL隱式變量的名字。MyExpressionBean是你自定義的JavaBean。 之后我們只要將這個(gè)初始化器配置到Spring中就可以在View設(shè)計(jì)中使用這個(gè)隱式變量了。Spring聲明參考格式:

<bean parent="dorado.expressionVarsInitializerRegister">
    <property name="contextInitializer">
        <bean class="xxx.xxx.xxx.XXXVarsInitializer" />
    </property>
</bean>

范例1:

vars.put("mysystem", System.getProperties());

測試用例:

${mysystem['java.home']}
${mysystem.get('java.home')}

范例2:

//ExpressionUtilsObject為dorado中的com.bstek.dorado.core.el.ExpressionUtilsObject
vars.put("myutil", SingletonBeanFactory.getInstance(ExpressionUtilsObject.class));

測試用例:

${myutil.getToday()}
${myutil.trim(${param['userId']})}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號