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

Mule ESB是一个使用Java语言编写的开源企业服务总线,企业服务总线英文Enterprise Service Bus,简称ESB。其相关源代码也托管在GitHub上,可以在https://github.com/mulesoft/mule这里找到相关的Source Code。

MuleESB在众多开源的ESB中处于领先者的地位,已拥有超过数百万的下载量,以及来自世界各地数十万个开发人员。MuleSoft公司也作为开源软件中的独角兽,2017年在纽交所成功上市。我们作为MuleSoft的重要合作伙伴也参与其中,在六年多的时间里,使用Mule ESB社区版实施,或者Mule ESB企业版实施,构建众多Mule ESB开发案例,帮助国内众多的企业成功上线企业集成项目。

专注Mule ESB社区版实施,分享开源中间件。我们的网站: http://www.enjoyingsoft.com,或者邮件联系我们Contact@EnjoyingSoft.com

我们使用Mule ESB开发的过程中,体会到它优秀的架构设计和高效的开发速度。同时也深感Mule ESB书籍,Mule ESB中文文档资料非常稀少,所以使用8篇文章来写Mule ESB的基础系列教程,讲解Mule ESB功能和开发。

1. 探索Mule Message结构

很多开发者在开始使用Mule开发,很大原因是因为Mule的图形化开发环境非常友好,同时Mule Esb Transport也非常多,但对Mule最重要的Mule message概念并不特别熟悉。本篇重点讲解Mule的Message。

上一篇教程中已经说到,Flow的结构和构成元素,在Flow中流动的就是Mule Message。

messageinflow.png

Mule Message是一个数据结构,也有相对应的Java Class。它包括几部分Payload,Property,Attachment。如下图所示:

mule-message.png

如何理解这幅图,大致可以和HTTP协议类比。

  • Property

    Mule Message的Property又分成Inbound Properties和Outbound Properties。这一点类似于HTTP协议的请求头和响应头。

  • Payload

    Mule的Payload是一个对象,类型是不固定的。可能是Stream,也可能是Hashmap,也可能是XML字符串。这一点类似于HTTP协议的请求正文,或者说是请求体。

  • Attachment

    Mule的Attachment就是消息的附件,这一点类似于HTTP协议中的multipartform-data请求。

HTTP-protocol-communication-schema.png

如果你想看到整个MuleMessage的结构,使用Mule的Logger组件可以很方便的看到Message完整的组成。使用Logger打印出message,logger组件会重载message的toString方法,打印出Pretty格式的message。

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
    <http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
    <flow name="loggertestFlow">
        <http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
        <set-payload value="#[&quot;Mule Message&quot;]" doc:name="Set Payload"/>
        <logger message="#[message]" level="INFO" doc:name="Logger"/>
    </flow>
</mule>

我们可以从下图的记录中找到和上图Message Structure相对应的节点。处于篇幅原因,做了简略处理。

org.mule.DefaultMuleMessage
{
  id=f88d0090-074c-11e9-89b7-0c5415358ba9
  payload=java.lang.String
  correlationId=<not set>
  correlationGroup=-1
  correlationSeq=-1
  encoding=UTF-8
  exceptionPayload=<not set>

Message properties:
  INVOCATION scoped properties:
  INBOUND scoped properties:
    accept=*/*
    accept-encoding=gzip, deflate, br
    accept-language=zh-CN,zh;q=0.9,en;q=0.8
    cache-control=no-cache
    connection=keep-alive
    content-length=2
    content-type=text/plain;charset=UTF-8
    host=localhost:8081
    http.listener.path=/
    http.method=POST
    http.query.params=ParameterMap{[]}
    http.query.string=
    http.relative.path=/
    http.remote.address=/127.0.0.1:57630
    http.request.path=/
    http.request.uri=/
    http.scheme=http
    http.uri.params=ParameterMap{[]}
    http.version=HTTP/1.1
  SESSION scoped properties:
}

2. Mule Message的Payload

Payload翻译成中文是负荷,负载的意思。它是Mule Message的主要部分,也是Mule处理的主要对象。我们后续说的数据转换就是对Payload的转换。注意Mule Message的Payload是有可能为空的,比如接收到一个Http Get请求,Http Get请求的请求体是空的,所以这个时候Mule Message的Payload是空的。

在Flow中,最常用的动作就是给payload赋值,给Payload赋值会使用set-payload组件。如果我们在Flow中想获取payload,可以使用MEL表达式。

下面的源代码表示payload的赋值和取值。

<flow name="payloadFlow">
        <http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
        <set-payload value="#[&quot;Mule Message&quot;]" doc:name="Set Payload"/>
        <logger message="#[payload]" level="INFO" doc:name="Logger"/>
</flow>

3. Mule Message的Property

Mule Message的Property是一个键值对,有name和对应的value。Mule Message有两种类型的Property,Inbound Properties和Outbound Properties。Inbound Properties或者Outbound Properties可以有多个Property,也就是多个键值对。

Inbound Properties是不可变的,是由Message Source产生的。就类似于Http的请求参数,是由用户的数据请求,经过Java的Servlet,或者Asp.Net等框架封装成Http Request对象。

Outbound Properties是可变的,我们在Mule的Flow中新增或者改变这些属性。注意,比如转换器,有些Mule Processor会自动增加有些属性。

在Mule中设定Property使用set-property组件,如果需要获取,同样使用MEL表达式。详细的MEL表达式,我们下篇会展开讲解。

<flow name="propertyFlow">
        <http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
        <set-property propertyName="#[&quot;userName&quot;]" value="#[&quot;Tom&quot;]" doc:name="Property"/>
</flow>

4. Mule Message的Attachment

Attachment,正如字面上意思,可以理解成消息的附件。想象一封邮件,有邮件发送人等头信息,也有邮件正文,同样还有邮件附件。和Property一样,Attachment也有两种类型,Inbound Attachment和Outbound Attachment。我们通常将一些大的对象作为附件传输。

使用set-attachment设置附件,这里将payload作为pdf文档附件供消费者下载。

<flow name="variableFlow">
        <http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
        <set-attachment attachmentName="#[&quot;doc&quot;]" value="#[payload]" contentType="application/pdf" doc:name="Attachment"/>
</flow>

5. Mule的Variable

Variable也就是变量,有几种类型的变量,或者说几种不同范围的变量,如下:Flow Variable,Session Variable,Record Variable。Flow Variable在一个Flow是有效的,Session Variable是可以跨Flow的,Record Variable则是处理数据列表时会用到。

这里不详细讲述。从使用上说,有些类似于Java里面的局部变量,Session变量,但不完全一致。后续实战文章会分析这一点。

在Mule里,使用set-variable和MEL表达式对变量做赋值和取值操作。

<flow name="attachmentFlow">
        <http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
        <set-variable variableName="orderNo" value="#[&quot;1238&quot;]" doc:name="Variable"/>
</flow>

6. 使用Java操作Mule Message

对程序员来说,千言万语不如代码,如何使用Java操作Mule Message呢?通过Java代码我们可以清楚的看到Mule Message的结构,成员变量和方法等。

public void explorMessage(MuleMessage message) {
    // 获取InboundProperty
    String requestPath = message.getInboundProperty("http.request.path");
    // 设定OutboundProperty
    message.setOutboundProperty("content-type", "application/json");
    // 获取Payload
    Object payload = message.getPayload();
    // 获取InboundAttachment
    DataHandler fileAttachment = message.getInboundAttachment("fileName");
    // 获取flow变量
    message.getProperty("flowVarTest", PropertyScope.INVOCATION);
}

下图是Mule Message的类图,类图中只列表了重要的方法和属性。


messagemodal.png

本文同步发文于EnjoyingSoft Blogs博客园CSDN

访问EnjoyingSoft 网站,获取更多Mule ESB 社区版 实施帮助。

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345