本篇主要介紹Mule表達(dá)式語(yǔ)言柴底,Mule Expression Language蚯撩,簡(jiǎn)稱MEL。MEL是一種輕量級(jí)咽弦,在Mule ESB使用的表達(dá)式語(yǔ)言徒蟆,可用于訪問(wèn)和計(jì)算Mule Message的Payload,Property和Variable型型。幾乎每一個(gè)Mule組件都可以使用MEL表達(dá)式段审。MEL表達(dá)式能夠幫助開(kāi)發(fā)者高效和優(yōu)雅地過(guò)濾,路由闹蒜,處理Mule message寺枉。關(guān)于Mule message基本概念,請(qǐng)參考第二篇和第三篇文章绷落。
Mule ESB是一個(gè)使用Java語(yǔ)言姥闪,基于Spring框架編寫的開(kāi)源企業(yè)服務(wù)總線,其相關(guān)源代碼托管在GitHub上砌烁。企業(yè)服務(wù)總線英文Enterprise Service Bus筐喳,簡(jiǎn)稱ESB。
MuleESB在眾多開(kāi)源的ESB中處于領(lǐng)先者的地位函喉,擁有來(lái)自世界各地?cái)?shù)十萬(wàn)個(gè)開(kāi)發(fā)人員避归,超過(guò)數(shù)百萬(wàn)的下載量。MuleSoft公司也作為開(kāi)源軟件中的獨(dú)角獸函似,2017年在紐交所成功上市槐脏。我們作為MuleSoft的重要合作伙伴也參與其中,在六年多的時(shí)間里撇寞,使用Mule ESB企業(yè)版開(kāi)發(fā)顿天,或者M(jìn)ule ESB社區(qū)版開(kāi)發(fā)堂氯,構(gòu)建了眾多Mule ESB實(shí)施案例,幫助國(guó)內(nèi)眾多的企業(yè)成功上線企業(yè)集成項(xiàng)目牌废。
專注Mule ESB社區(qū)版實(shí)施咽白,分享開(kāi)源中間件。我們的網(wǎng)站: http://www.enjoyingsoft.com鸟缕,或者郵件聯(lián)系我們Contact@EnjoyingSoft.com
我們使用Mule ESB開(kāi)發(fā)的過(guò)程中晶框,體會(huì)到它優(yōu)秀的架構(gòu)設(shè)計(jì)和高效的開(kāi)發(fā)速度。同時(shí)也深感Mule ESB開(kāi)發(fā)書(shū)籍懂从,Mule ESB中文文檔資料非常稀少授段,所以使用8篇文章來(lái)寫基礎(chǔ)Mule ESB開(kāi)發(fā)教程,講解如何使用Mule ESB開(kāi)發(fā)番甩。
- EnjoyingSoft之Mule ESB開(kāi)發(fā)教程第一篇:初識(shí)Mule ESB
- EnjoyingSoft之Mule ESB開(kāi)發(fā)教程第二篇:Mule ESB基本概念
- EnjoyingSoft之Mule ESB開(kāi)發(fā)教程第三篇:Mule message structure - Mule message結(jié)構(gòu)
- EnjoyingSoft之Mule ESB開(kāi)發(fā)教程第四篇:Mule Expression Language - MEL表達(dá)式
- EnjoyingSoft之Mule ESB開(kāi)發(fā)教程第五篇:控制消息的流向-數(shù)據(jù)路由
- EnjoyingSoft之Mule ESB開(kāi)發(fā)教程第六篇:Data Transform - 數(shù)據(jù)轉(zhuǎn)換
- EnjoyingSoft之Mule ESB開(kāi)發(fā)教程第七篇:SOAP Web Service的消費(fèi)和創(chuàng)建
- EnjoyingSoft之Mule ESB開(kāi)發(fā)教程第八篇:使用API構(gòu)建Rest Service
1. MEL的優(yōu)勢(shì)
在Mule ESB上有很多方法可以操作Mule Message侵贵,比如Java語(yǔ)言或者其他腳本語(yǔ)言(比如JavaScript等)。但是MEL表達(dá)式是Mule推薦使用缘薛,在Mule應(yīng)用中的一個(gè)統(tǒng)一和標(biāo)準(zhǔn)的方法窍育。
- MEL表達(dá)式為開(kāi)發(fā)人員提供了一個(gè)一致的標(biāo)準(zhǔn)化語(yǔ)言,用來(lái)訪問(wèn)和計(jì)算Mule Message的Payload(負(fù)載)宴胧,Property(屬性)和Variable(變量)漱抓。
- MEL基于Mule特定的對(duì)象,Studio中提供auto-complete(自動(dòng)完成恕齐,語(yǔ)法提示)的功能乞娄,幫助開(kāi)發(fā)者快速編碼。
- 更重要的是显歧,Mule的絕大多數(shù)組件都支持MEL补胚,比如路由組件,過(guò)濾組件等追迟。
MEL的示例溶其,這個(gè)示例在在Mule的Logger組件中使用MEL表達(dá)式獲取FlowVars。
從下圖可以看到敦间,我們?cè)贚ogger組件中使用MEL表達(dá)式瓶逃,能夠提供語(yǔ)法提示,該提示帶出了上一步設(shè)定的customerNo變量廓块。
XML配置如下:
<flow name="mel-flow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<set-variable variableName="customerNo" value="#[1008]" doc:name="customerNo"/>
<logger message="The customerNo is #[flowVars.customerNo]" level="INFO" doc:name="Logger"/>
</flow>
注意:MEL是一種表達(dá)式,和腳本語(yǔ)言類似带猴,但并不相同昔汉。表達(dá)式通常用于動(dòng)態(tài)獲取值或者設(shè)定值,或?qū)?shù)據(jù)進(jìn)行簡(jiǎn)單的操作会通。表達(dá)式語(yǔ)言和腳本語(yǔ)言之間在功能上存在重疊裳涛,但如果您編寫的內(nèi)容非常復(fù)雜,需要的不僅僅是幾行代碼,或者您需要包含條件邏輯鹃彻,那么腳本語(yǔ)言通常會(huì)更有用僚饭。如果簡(jiǎn)單的獲取或設(shè)定值革骨,調(diào)用方法或執(zhí)行函數(shù),則使用表達(dá)式則更方便。
2. MEL的使用場(chǎng)景
MEL表達(dá)式常用的使用場(chǎng)景大概可以分成三種腾啥。
- 獲取值
-
#[payload]
- 表示獲取message的負(fù)載
-
#[message.inboundProperties.'http.query.params'.customerNo]
- 表示獲取查詢參數(shù)customerNo
-
#[payload.callMethod(parameters)
- 表示調(diào)用payload對(duì)象的callMethod方法疮跑,并獲取方法返回值
-
#[xpath('//root/element')]
- 表示使用xpath語(yǔ)法解析并獲取相應(yīng)節(jié)點(diǎn)內(nèi)容。
-
- 條件比較掀潮,返回的結(jié)果就是布爾變量
#[payload.amount > 2000]
-
#[message.inboundProperties.'http.method' == 'GET']
- 表示判斷HTTP請(qǐng)求是不是GET方法
- 設(shè)定值,通常用于Message Enricher組件。
-
#[flowVars.dbResult]
- 這里表示相應(yīng)的值設(shè)定到dbResult變量中恶迈。
-
3. MEL的示例
-
使用表達(dá)式提取值斥滤,根據(jù)消息的內(nèi)容宰闰,屬性決定執(zhí)行流程咐容。在下面的示例中,payload是一個(gè)Java對(duì)象评雌,我們根據(jù)購(gòu)買類型斤吐,將訂單分發(fā)路由到不同的JMS消息隊(duì)列中。
<choice> <when expression="#[payload.getOrderType() == 'book']"> <jms:outbound-endpoint queue="bookQueue" /> </when> <when expression="#[payload.getOrderType() == 'music']"> <jms:outbound-endpoint queue="musicQueue" /> </when> </choice>
-
使用表達(dá)式提取值伪冰,并將值傳遞給Connector寨辩,如下示例就是使用MEL計(jì)算的值設(shè)定SMTP Connector的郵件標(biāo)題,郵件接收人等秸滴。
<smtp:outbound-endpoint from="#[flowVars.mailFrom]" to="#[flowVars.mailTo]" subject="#[payload.mailSubject]" doc:name="SMTP"/>
-
如果payload是Java對(duì)象内颗,可以調(diào)用payload方法,獲取方法的返回值。示例就說(shuō)調(diào)用calAmount方法峭判,并打印計(jì)算出來(lái)的金額林螃。
<logger message="#[payload.calAmount()]" />
4. MEL的上下文對(duì)象
我們?cè)谏鲜龅腗EL表達(dá)式示例中可以看到MEL有多個(gè)部分組成,第一部分就是上下文對(duì)象俺泣。MEL常見(jiàn)的上下文對(duì)象如下:
上下文對(duì)象 | 說(shuō)明 |
---|---|
#[server] | 當(dāng)前服務(wù)器治宣,可以獲取服務(wù)器的時(shí)間急侥,JDK版本等,如#[server.dateTime]侮邀,#[server.javaVersion] |
#[mule] | 當(dāng)前Mule實(shí)例坏怪,可以獲取Mule的版本,目錄等绊茧。如#[mule.version] |
#[app] | 當(dāng)前Mule應(yīng)用的實(shí)例铝宵,可以獲取應(yīng)用的名稱等。如#[app.name] |
#[message] | 這個(gè)是我們最經(jīng)常使用的對(duì)象华畏,就說(shuō)Mule message鹏秋。如#[message.payload],#[message.inboundProperties.'http.query.params'.customerNo]等 |
server上下文對(duì)象的常用屬性:
Field | Field描述 |
---|---|
dateTime | 系統(tǒng)當(dāng)前時(shí)間 |
host | 主機(jī)名 |
ip | 主機(jī)IP |
osName | 操作系統(tǒng)名稱 |
userName | 當(dāng)前用戶 |
userDir | 當(dāng)前用戶工作目錄 |
mule上下文對(duì)象的常用屬性:
Field | Field描述 |
---|---|
home | Mule Runtime的安裝目錄 |
version | Mule Runtime的版本 |
nodeId | 集群下的本機(jī)ID |
clusterId | 集群ID |
app上下文對(duì)象的常用屬性:
Field | Field描述 |
---|---|
name | Mule App應(yīng)用名稱 |
workdir | Mule App工作目錄 |
message上下文對(duì)象的常用屬性:
Field | Field描述 |
---|---|
id | message的唯一ID |
rootId | message的根ID |
payload | message的負(fù)載 |
inboundProperties | message的inbound頭信息 |
inboundAttachments | message的inbound附件信息 |
outboundProperties | message的outbound頭信息 |
outboundAttachments | message的outbound附件信息 |
5. MEL的Variable
不同于第4點(diǎn)提到的上下文對(duì)象亡笑,MEL中還可以使用變量侣夷,使用變量并不要求在表達(dá)式中使用上下文對(duì)象。變量是頂層的標(biāo)識(shí)符仑乌。MEL中常見(jiàn)的變量如下:
- flowVars - flowVars的有效范圍是在一個(gè)Flow中百拓,定義flowVars之后,后續(xù)的Message Processor都可以使用晰甚。
- sessionVars - 在跨Flow通信時(shí)衙传,可以使用sessionVars來(lái)傳遞變量。需要注意的是厕九,sessionVars并不總是有效的蓖捶,其實(shí)取決于Inboud Endpoint的類型。后續(xù)再出專題介紹flowVars和sessionVars等之間的區(qū)別扁远。
#[flowVars.foo = sessionVars.bar]
上述的表達(dá)式的意思是俊鱼,將session變量賦值給flow變量。
6. MEL訪問(wèn)屬性
-
點(diǎn)語(yǔ)法畅买。適用對(duì)象通常是Java Pojo并闲。MEL中可以使用點(diǎn)語(yǔ)法來(lái)訪問(wèn)相關(guān)的對(duì)象屬性,同樣對(duì)象屬性的屬性也是可以用點(diǎn)號(hào)來(lái)訪問(wèn)的皮获。
#[message.payload.item.name]
-
Null安全性訪問(wèn)焙蚓。Java編程中經(jīng)常遇到NullPointerException錯(cuò)誤纹冤,也就是說(shuō)對(duì)空對(duì)象進(jìn)行訪問(wèn)操作會(huì)報(bào)錯(cuò)洒宝。而在MEL表達(dá)式,可以通過(guò)點(diǎn)語(yǔ)法.?來(lái)避免出錯(cuò)萌京。如下示例雁歌,即使item為null,該表達(dá)式仍然不會(huì)報(bào)錯(cuò)知残,它會(huì)返回null值靠瞎。
#[message.payload.?item.name]
-
屬性名稱的轉(zhuǎn)義。如果屬性名稱有特殊字符,那么使用點(diǎn)語(yǔ)法會(huì)遇到問(wèn)題乏盐,這個(gè)時(shí)候可以單引號(hào)進(jìn)行轉(zhuǎn)義佳窑。如下示例,http.query.params是一個(gè)整體父能。我們?cè)L問(wèn)這個(gè)屬性名神凑,必須使用單引號(hào)進(jìn)行轉(zhuǎn)義。
#[message.inboundProperties.'http.query.params'.customerNo]
-
中括號(hào)語(yǔ)法何吝。如果對(duì)象是數(shù)組溉委,或者M(jìn)ap,那么可以使用中括號(hào)進(jìn)行訪問(wèn)
#[payload[5]]
#[payload['userName']]
7. MEL操作符
常用的操作符如下爱榕,和普通的開(kāi)發(fā)語(yǔ)言類似瓣喊。還有更多的操作符可以查閱官方手冊(cè)。
-
算術(shù)運(yùn)算符 + - / * %
#[2 + 4]
#['fu' + 'bar']
-
比較運(yùn)算符 == != > < >= <=
#['A' == 'A']
#[7 > 5]
-
邏輯運(yùn)算符 && ||
#[(a == b) && (c != d)]
-
三元操作符
#[lastname = (name == 'Smith') ? 'Smith' : 'Unknown']
本文同步發(fā)文于EnjoyingSoft Blogs 黔酥,博客園藻三,CSDN
訪問(wèn)EnjoyingSoft 網(wǎng)站,獲取更多Mule ESB 社區(qū)版 實(shí)施幫助絮爷。
歡迎轉(zhuǎn)載趴酣,但必須保留原文和此段聲明,且在文章頁(yè)面明顯位置給出原文鏈接坑夯,否則保留追究法律責(zé)任的權(quán)利岖寞。