本篇主要介绍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 社区版 实施帮助。

欢迎转载,但必须保留原文和此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

EnjoyingSoft之Mule ESB开发教程第四篇:Mule Expression Language - MEL表达式的更多相关文章

  1. EnjoyingSoft之Mule ESB开发教程第三篇:Mule message structure - Mule message结构

    目录 1. 探索Mule Message结构 2. Mule Message的Payload 3. Mule Message的Property 4. Mule Message的Attachment 5 ...

  2. EnjoyingSoft之Mule ESB开发教程第六篇:Data Transform - 数据转换

    目录 1. 数据转换概念 2. 数据智能感知 - DataSense 3. 简单数据转换组件 3.1 Object to JSON 3.2 JSON to XML 3.3 JSON to Object ...

  3. EnjoyingSoft之Mule ESB开发教程系列第五篇:控制消息的流向-数据路由

    目录 1. 使用场景 2. 基于消息头的路由 2.1 使用JSON提交订单的消息 2.2 使用XML提交订单的消息 2.3 使用Choice组件判断订单格式 3. 基于消息内容的路由 4. 其他控制流 ...

  4. EnjoyingSoft之Mule ESB开发教程第一篇:初识Mule ESB

    目录 1. Mule ESB基本介绍 2. Mule ESB社区版和企业版 3. Mule ESB常用场景 4. Mule ESB软件安装 客户端安装 服务端安装 5. 第一个Mule ESB应用- ...

  5. EnjoyingSoft之Mule ESB开发教程第二篇:Mule ESB基本概念

    目录 1. 使用Anypoint Studio开发 2. Mule ESB Application Structure - Mule ESB应用程序结构 3. Mule ESB Application ...

  6. Senparc.Weixin.MP SDK 微信公众平台开发教程(四):Hello World

    =============  以下写于2013-07-20 ============= 这一篇文章其实可以写在很前面,不过我还是希望开发者们尽多地了解清楚原理之后再下手. 通过上一篇Senparc.W ...

  7. 微信公众账号开发教程(四)自定义菜单(含实例源码)——转自http://www.cnblogs.com/yank/p/3418194.html

    微信公众账号开发教程(四)自定义菜单 请尊重作者版权,如需转载,请标明出处. 应大家强烈要求,将自定义菜单功能课程提前. 一.概述: 如果只有输入框,可能太简单,感觉像命令行.自定义菜单,给我们提供了 ...

  8. spring cloud系列教程第四篇-Eureka基础知识

    通过前三篇文章学习,我们搭建好了两个微服务工程.即:order80和payment8001这两个服务.有了这两个基础的框架之后,我们将要开始往里面添加东西了.还记得分布式架构的几个维度吗?我们要通过一 ...

  9. [051] 微信公众平台开发教程第22篇-怎样保证access_token长期有效

    为了使第三方开发人员能够为用户提供很多其它更有价值的个性化服务,微信公众平台开放了很多接口,包含自己定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等,开发人员在调用这些接口时.都须要 ...

随机推荐

  1. 深入理解Amazon Alexa Skill(三)

    本节来讨论Alexa Skill中涉及到的授权问题. Alexa内功能的授权 Alexa会发给skill用户的token,然后skill代码使用这个token来访问Web API访问用户的Alexa内 ...

  2. Win8Metro(C#)数字图像处理--2.27图像加法运算

    原文:Win8Metro(C#)数字图像处理--2.27图像加法运算  [函数名称] 图像加法函数AddProcess(WriteableBitmap src, WriteableBitmap a ...

  3. Win10《芒果TV》商店内测版更新至v3.7.65.0:跨平台UI新体验,铺路SP

    Win10<芒果TV - Preview>是Win10<芒果TV>官方唯一指定内测预览版,最新的改进和功能更新将会在此版本优先体验. 春去夏来,初心犹在,Win10<芒果 ...

  4. 规则“Microsoft Visual Studio 2008 的早期版本”失败。此计算机上安装了 Microsoft Visual Studio 2008 的早期版本。请在安装 SQL Server 2008 前将 Microsoft Visual Studio 2008 升级到 SP1。

    今天重装了一下系统后,需要装开发工具,我用的开发工具是Visual Studio2008 和SQL Server2008R2,装完Visual Studio2008的时候在装数据库的时候却出现这样的问 ...

  5. Android零基础入门第38节:初识Adapter

    原文:Android零基础入门第38节:初识Adapter 在上一节一起了解了ListView的简单使用,那么本节继续来学习与ListView有着千丝万缕的Adapter. 一.了解MVC模式 在开始 ...

  6. UWP入门(四)--设置控件样式

    原文:UWP入门(四)--设置控件样式 官方定义:可以使用 XAML 框架通过多种方式自定义应用的外观. 通过样式可以设置控件属性,并重复使用这些设置,以便保持多个控件具有一致的外观. 可分享至不同e ...

  7. 使用Visual Studio开发Python

    Python优秀的集成开发环境有PyCharm,Visual Studio Code等,当然你仍然可以使用Visual Studio进行开发.如果你熟悉Visual Studio,使用Visual S ...

  8. Mysql 自定义HASH索引带来的巨大性能提升

    有这样一个业务场景,需要在2个表里比较存在于A表,不存在于B表的数据.表结构如下: T_SETTINGS_BACKUP | CREATE TABLE `T_SETTINGS_BACKUP` ( `FI ...

  9. MyBatis从入门到精通(一):MyBatis入门

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. MyBatis简介 ​ 2001 ...

  10. 01 Javascript简介(了解)

    Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) JavaScript历史背景介绍 布 ...