mule in action翻譯12 : 2.4 使用Mule表達式語言
2.4 使用Mule表達式語言
mule表達式語言帶來了配置的動态性。mule提供豐富的表達式語言,
供你在配置檔案的不同地方處理複雜邏輯。
表達式重載 mule表達式計算架構在 version3.3 進行了大改進。
形式如 #[evaluator:expression] ,
需要兩個參數(expression和evaluator)的老文法已經過時, 本書現統一使用新文法。
mule表達式語言 ,也稱為MEL,是基于MVFLEX表達式語言的(MVEL),它的程式設計功能齊全,
mule特有的變量和函數也豐富了它的功能。
你可以線上擷取MEL的完整文檔,是以這裡我們隻是泛泛的講一下一般性的知識。
(你也可檢視附錄擷取更多細節)
你可以使用MEL 做如下的事情:
1、使用classpath 下的可用的java類
2、友善的對list、map、array以及bean的屬性進行導航式通路
3、表達複雜的邏輯,包含三元表達式。
4、定義本地變量,并以聲明方式使用它。
mule綁定了一系列頂層的對象,作為通路mule執行時上下文的入口,
這也是目前消息的上下文入口。
現在,有四個上下文對象可用:
1、server --包含硬體、作業系統、使用者及網絡接口的屬性消息,例如 server.ip
2、mule --mule執行個體的屬性資訊,例如 mule.version
3、app --進行mule表達式計算的mule應用。
4、message--目前正在處理的消息,例如 message.correlationId 或 message.payload
mule也提供了幫助方法作為計算上下文的成員.目前有兩個可用的幫助方法:
1、xpath--可友善的從payload的XML或别的MEL表達式中提取值,例如xpath('/orders/order[0]')
2、regex--傳回比對payload或别的MEL表達式的數組,例如 regex('^(TO|From|Cc):')
擴充MEL 為了定義定制導入、可重用的函數或全局别名可以擴充MEL。更多消息參考附錄A,的A.2部分。
可以在相同的表達式中放置多個聲明,但要使用分号隔開。
最後一個聲明的的值将将作為整個表達式的值。
例如, 計算下面的表達式:
targetDir = new java.io.File(server.tmpDir, 'target');
targetDir.mkdir();
targetDir
将傳回java.io.File 類型的targetDir。
建議在在xml配置中,在任何屬性中使用表達式時用方括号 #[] 把在表達式括起來。
下例中沒有使用方括号,但也能正常使用;
<when expression="message.inboundProperties['valid']">
但建議寫成:
<when expression="#[message.inboundProperties['valid']]">
這不适用于表達式元件,因為其中的 #[]會被忽略。
2.4.1 使用表達式
在xml配置檔案中,表達式幾乎可以用在所有的要求傳回字元串的地方。
因為表達式是在運作時進行計算的--當消息流經mule時,
是以 既要使用目前消息又要使用到mule啟動時讀取的值(比如mule必須綁定的一個端口)的表達式
你是不能使用的。
清單2.14顯示了怎樣使用java.util.UUID動态的建立事務ID,并把它傳遞到XSLT轉換器。
Listing 2.14 Using an expression to create a dynamic XSLT parameter
<mulexml:xslt-transformer xsl-file="to_payment_processor_call.xsl">
<mulexml:context-property key="transactionId"
value="#[java.util.UUID.randomUUID().toString()]" />
</mulexml:xslt-transformer>
消息處理器會公平的使用表達式。在4.3.5,我們會讨論message enricher,
一個嚴重依賴表達式的消息處理器。另外一個依賴于表達式的消息處理器是logger。
看清單2.15 中是怎樣使用xpath記錄發票ID的。
注意 通過簡寫的 bean屬性 value會調用 getValue()方法。
Listing 2.15 Logging a value extracted with XPath
<logger message="#[xpath('/invoice/@id').value]"
category="com.prancingdonkey.service.Invoice.id"
level="INFO" />
使用表達式較多的另外一種方式是作為路由的邏輯條件,像選擇路由和過濾器路由。
true 或 false 條件判斷中可以使用MEL的布爾型傳回值。
String類型的值可以用來進行布爾計算,但我們更傾向于傳回布爾型的值。
6.2節中讨論的配置patterns,為了使配置更簡明也會使用較多的表達式。
清單2.16 展示了一個驗證pattern,它使用簡單的字元串表示接受還是拒絕消息。
它也使用表達式檢查目前消息是否有附件。
Listing 2.16 The validator configuration pattern heavily relies on expressions.
<pattern:validator name="ensureAttached"
inboundAddress="vm://ensure.attached"
outboundAddress="vm://valid.request.handler"
ackExpression="#['OK']"
nackExpression="#['ERROR: no attachment!']">
<expression-filter expression="#[!(message.inboundAttachments.empty)]" />
</pattern:validator>
表達式也可以用用來進行endpoint的配置。
清單2.17 展示了一個允許動态取回股票市場曆史資料。
這個流接收 股票代碼辨別符 作為payload,但他收到的不是
java.lang.String類型的(而是byte[]). 替代方案是,在建構HTTP patch前它使用一個payload 求值器
取出目前的payload内容,并把它轉換成java.lang.String 。
Listing 2.17 Expressions in endpoint URIs can be resolved at runtime by evaluators.
<flow name="tickerFetcher">
<vm:inbound-endpoint path="ticker.fetcher"
exchange-pattern="request-response" />
<http:outbound-endpoint
exchange-pattern="request-response"
host="www.google.com"
port="80"
path="finance/historical?q=#[message.payloadAs(java.lang.String)]" />
</flow>
你自己的代碼中也能使用mule的表達式計算架構。
你需要做的唯一的事就是引用mule的上下文,它允許你使用表達式語言電腦:
ExpressionLanguage mel = muleContext.getExpressionLanguage();
String applicationName = mel.evaluate("app.name");
你可能發現電腦的求值方法是相當容易了解的。
更多請參考 Mule API SDK (www.mulesoft.org/docs/site/current3/apidocs/).
支援注解 表達式也可以使用注解。但要使用@Mule注解,像下面所示:
@Mule("#[app.name]")
String applicationName
本節不可能講解所有的MEL的東西。但本身其餘部分,你會看到大量的MEL的使用。