1. 程式人生 > >EnjoyingSoft之Mule ESB開發教程第四篇:Mule Expression Language - MEL表示式

EnjoyingSoft之Mule ESB開發教程第四篇:Mule Expression Language - MEL表示式

目錄

本篇主要介紹Mule表示式語言,Mule Expression Language,簡稱MEL。MEL是一種輕量級,在Mule ESB使用的表示式語言,可用於訪問和計算Mule Message的Payload,Property和Variable。幾乎每一個Mule元件都可以使用MEL表示式。MEL表示式能夠幫助開發者高效和優雅地過濾,路由,處理Mule message。關於Mule message基本概念,請參考

第二篇第三篇文章。

Mule ESB是一個使用Java語言,基於Spring框架編寫的開源企業服務匯流排,其相關原始碼託管在GitHub上。企業服務匯流排英文Enterprise Service Bus,簡稱ESB。

MuleESB在眾多開源的ESB中處於領先者的地位,擁有來自世界各地數十萬個開發人員,超過數百萬的下載量。MuleSoft公司也作為開源軟體中的獨角獸,2017年在紐交所成功上市。我們作為MuleSoft的重要合作伙伴也參與其中,在六年多的時間裡,使用Mule ESB企業版開發,或者Mule ESB社群版開發,構建了眾多Mule ESB實施案例,幫助國內眾多的企業成功上線企業整合專案。

我們使用Mule ESB開發的過程中,體會到它優秀的架構設計和高效的開發速度。同時也深感Mule ESB開發書籍,Mule ESB中文文件資料非常稀少,所以使用8篇文章來寫基礎Mule ESB開發教程,講解如何使用Mule ESB開發。

1. MEL的優勢

在Mule ESB上有很多方法可以操作Mule Message,比如Java語言或者其他指令碼語言(比如JavaScript等)。但是MEL表示式是Mule推薦使用,在Mule應用中的一個統一和標準的方法。

  • MEL表示式為開發人員提供了一個一致的標準化語言,用來訪問和計算Mule Message的Payload(負載),Property(屬性)和Variable(變數)。
  • MEL基於Mule特定的物件,Studio中提供auto-complete(自動完成,語法提示)的功能,幫助開發者快速編碼。
  • 更重要的是,Mule的絕大多陣列件都支援MEL,比如路由元件,過濾元件等。

MEL的示例,這個示例在在Mule的Logger元件中使用MEL表示式獲取FlowVars。

從下圖可以看到,我們在Logger元件中使用MEL表示式,能夠提供語法提示,該提示帶出了上一步設定的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是一種表示式,和指令碼語言類似,但並不相同。表示式通常用於動態獲取值或者設定值,或對資料進行簡單的操作。表示式語言和指令碼語言之間在功能上存在重疊,但如果您編寫的內容非常複雜,需要的不僅僅是幾行程式碼,或者您需要包含條件邏輯,那麼指令碼語言通常會更有用。如果簡單的獲取或設定值,呼叫方法或執行函式,則使用表示式則更方便。

2. MEL的使用場景

MEL表示式常用的使用場景大概可以分成三種。

  • 獲取值
    • #[payload]
      • 表示獲取message的負載
    • #[message.inboundProperties.'http.query.params'.customerNo]
      • 表示獲取查詢引數customerNo
    • #[payload.callMethod(parameters)
      • 表示呼叫payload物件的callMethod方法,並獲取方法返回值
    • #[xpath('//root/element')]
      • 表示使用xpath語法解析並獲取相應節點內容。
  • 條件比較,返回的結果就是布林變數
    • #[payload.amount > 2000]
    • #[message.inboundProperties.'http.method' == 'GET']
      • 表示判斷HTTP請求是不是GET方法
  • 設定值,通常用於Message Enricher元件。
    • #[flowVars.dbResult]
      • 這裡表示相應的值設定到dbResult變數中。

3. MEL的示例

  1. 使用表示式提取值,根據訊息的內容,屬性決定執行流程。在下面的示例中,payload是一個Java物件,我們根據購買型別,將訂單分發路由到不同的JMS訊息佇列中。

    <choice>
       <when expression="#[payload.getOrderType() == 'book']">
            <jms:outbound-endpoint queue="bookQueue" />
        </when>
       <when expression="#[payload.getOrderType() == 'music']">
            <jms:outbound-endpoint queue="musicQueue" />
        </when>
    </choice>
  2. 使用表示式提取值,並將值傳遞給Connector,如下示例就是使用MEL計算的值設定SMTP Connector的郵件標題,郵件接收人等。

    <smtp:outbound-endpoint from="#[flowVars.mailFrom]" to="#[flowVars.mailTo]" subject="#[payload.mailSubject]"  doc:name="SMTP"/>
  3. 如果payload是Java物件,可以呼叫payload方法,獲取方法的返回值。示例就說呼叫calAmount方法,並列印計算出來的金額。

    <logger message="#[payload.calAmount()]" />

4. MEL的上下文物件

我們在上述的MEL表示式示例中可以看到MEL有多個部分組成,第一部分就是上下文物件。MEL常見的上下文物件如下:

上下文物件 說明
#[server] 當前伺服器,可以獲取伺服器的時間,JDK版本等,如#[server.dateTime],#[server.javaVersion]
#[mule] 當前Mule例項,可以獲取Mule的版本,目錄等。如#[mule.version]
#[app] 當前Mule應用的例項,可以獲取應用的名稱等。如#[app.name]
#[message] 這個是我們最經常使用的物件,就說Mule message。如#[message.payload],#[message.inboundProperties.'http.query.params'.customerNo]等

server上下文物件的常用屬性:

Field Field描述
dateTime 系統當前時間
host 主機名
ip 主機IP
osName 作業系統名稱
userName 當前使用者
userDir 當前使用者工作目錄

mule上下文物件的常用屬性:

Field Field描述
home Mule Runtime的安裝目錄
version Mule Runtime的版本
nodeId 叢集下的本機ID
clusterId 叢集ID

app上下文物件的常用屬性:

Field Field描述
name Mule App應用名稱
workdir Mule App工作目錄

message上下文物件的常用屬性:

Field Field描述
id message的唯一ID
rootId message的根ID
payload message的負載
inboundProperties message的inbound頭資訊
inboundAttachments message的inbound附件資訊
outboundProperties message的outbound頭資訊
outboundAttachments message的outbound附件資訊

5. MEL的Variable

不同於第4點提到的上下文物件,MEL中還可以使用變數,使用變數並不要求在表示式中使用上下文物件。變數是頂層的識別符號。MEL中常見的變數如下:

  • flowVars - flowVars的有效範圍是在一個Flow中,定義flowVars之後,後續的Message Processor都可以使用。
  • sessionVars - 在跨Flow通訊時,可以使用sessionVars來傳遞變數。需要注意的是,sessionVars並不總是有效的,其實取決於Inboud Endpoint的型別。後續再出專題介紹flowVars和sessionVars等之間的區別。
#[flowVars.foo = sessionVars.bar]

上述的表示式的意思是,將session變數賦值給flow變數。

6. MEL訪問屬性

  1. 點語法。適用物件通常是Java Pojo。MEL中可以使用點語法來訪問相關的物件屬性,同樣物件屬性的屬性也是可以用點號來訪問的。

    #[message.payload.item.name]
  2. Null安全性訪問。Java程式設計中經常遇到NullPointerException錯誤,也就是說對空物件進行訪問操作會報錯。而在MEL表示式,可以通過點語法.?來避免出錯。如下示例,即使item為null,該表示式仍然不會報錯,它會返回null值。

    #[message.payload.?item.name]
  3. 屬性名稱的轉義。如果屬性名稱有特殊字元,那麼使用點語法會遇到問題,這個時候可以單引號進行轉義。如下示例,http.query.params是一個整體。我們訪問這個屬性名,必須使用單引號進行轉義。

    #[message.inboundProperties.'http.query.params'.customerNo]
  4. 中括號語法。如果物件是陣列,或者Map,那麼可以使用中括號進行訪問

    #[payload[5]]
    #[payload['userName']]

7. MEL操作符

常用的操作符如下,和普通的開發語言類似。還有更多的操作符可以查閱官方手冊。

  1. 算術運算子 + - / * %
  2. 比較運算子 == != > < >= <=
  3. 邏輯運算子 && ||

本文同步發文於EnjoyingSoft之Mule ESB開發教程第四篇:Mule Expression Language - MEL表示式

訪問EnjoyingSoft 網站,獲取更多Mule ESB 實施,Mule ESB 社群版 實施,Mule ESB實施,Mule ESB社群版實施幫助。

歡迎轉載,但必須保留原文和此段宣告,且在文章頁面明顯位置給出原文連結,否則保留追究法律責任的權利。