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 BlogsCSDN簡書

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM