1 配置效果图

2 应用的配置文件

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

 <mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:json="http://www.mulesoft.org/schema/mule/json"
xmlns:ajax="http://www.mulesoft.org/schema/mule/ajax" 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" version="CE-3.4.0" 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/ajax http://www.mulesoft.org/schema/mule/ajax/current/mule-ajax.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd"> <ajax:connector name="Ajax" serverUrl="http://0.0.0.0:9092/reservation" resourceBase="${app.home}/docroot" jsonCommented="true" doc:name="Ajax" /> <!-- 航班预定流,主要通过调用processReservation来完成航班信息的处理 -->
<flow name="makeReservation">
<ajax:inbound-endpoint channel="/searchFlights" connector-ref="Ajax" responseTimeout="10000" doc:name="Ajax" />
<flow-ref name="processReservation" doc:name="processReservation"/>
</flow> <!--
航班预定信息处理流
对航班的安排做的假设:
航班号以3结尾,不可获得,直接抛出FlightUnavailableException异常
航班号不是以3结尾,可进入下一步处理:
航班号以2结尾,可取得座位信息'20A';否则抛出没有座位信息异常'No seat info available',并把'No seat info available'赋给座位信息部分
-->
<flow name="processReservation"> <json:json-to-object-transformer returnClass="org.mule.example.ReservationRequest" doc:name="JSON to ReservationRequest" /> <!-- 把请求的负载保存到session对象中(payload的类型为ReservationRequest) -->
<set-session-variable variableName="reservationRequest" value="#[payload]" doc:name="Save orignal request in Session" /> <!-- 设置响应消息的负载 -->
<set-payload value="#[new org.mule.example.ReservationResponse()]" doc:name="Set ReservationResponse Payload" /> <!-- 把请求消息中的flighs设置到响应消息中 (payload的类型为ReservationResponse) -->
<expression-component doc:name="Add request flight to response">
<![CDATA[payload.setFlights(reservationRequest.flights)]]>
</expression-component> <set-variable variableName="totalPrice" value="#[0]" doc:name="Initialize totalPrice" /> <!-- 设置一个totalPrice变量,值为0 --> <!-- 迭代处理payload(payload的类型为ReservationResponse,里面有请求信息flights) -->
<foreach collection="#[payload.flights]" doc:name="Foreach on flights">
<scripting:transformer doc:name="Search flight availability">
<scripting:script engine="Groovy"><![CDATA[
if (payload.flightNumber.endsWith('3'))
throw new org.mule.example.FlightUnavailableException()
else
payload]]>
</scripting:script>
</scripting:transformer> <!--
此处声明了一个地址为vm://acquireFlightPriceQueue VM出站端点,即把响应消息扔到了acquireSeatsInfoQueue队列
而acquireSeatsInfo流,在地址vm://acquireFlightPriceQueue上等待请求
exchange-pattern="request-response" 表示该VM出站端点 等待acquireSeatsInfo流给的响应
-->
<vm:outbound-endpoint exchange-pattern="request-response" path="acquireSeatsInfoQueue" doc:name="Acquire Seats Info"/>
<!-- 再把响应消息扔到了acquireFlightPriceQueue队列,等待响应 -->
<vm:outbound-endpoint exchange-pattern="request-response" path="acquireFlightPriceQueue" doc:name="Acquire Flight Price" /> <!-- 更新totalPrice变量的值,把本次迭代的票价加到总价中 -->
<set-variable variableName="totalPrice" value="#[totalPrice + payload.ticketPrice]" doc:name="Add price to totalPrice" />
</foreach> <expression-component doc:name="Add total price to reservation">
<![CDATA[payload.totalPrice = flowVars['totalPrice']]]>
</expression-component>
<!-- 把响应对象转换为JSON, 航班预定处理结束 -->
<json:object-to-json-transformer doc:name="Object to JSON" /> <!-- 异常捕获区 -->
<choice-exception-strategy doc:name="Choice Exception Strategy">
<!-- -->
<catch-exception-strategy when="#[exception.causedBy(org.mule.example.FlightUnavailableException)]" doc:name="Catch Exception Strategy">
<scripting:transformer doc:name="Add no avaiilability error">
<scripting:script engine="Groovy">
<![CDATA[
def payload = new org.mule.example.ReservationResponse()
payload.addError('There is no availability for the selected flight!')
payload]]>
</scripting:script>
</scripting:transformer>
<json:object-to-json-transformer doc:name="Object to JSON" />
</catch-exception-strategy> <catch-exception-strategy doc:name="Catch Exception Strategy">
<scripting:transformer doc:name="Add exception message">
<scripting:script engine="Groovy">
<![CDATA[
def payload = new org.mule.example.ReservationResponse()
payload.addError('Error processing request!')
payload]]>
</scripting:script>
</scripting:transformer>
<set-property propertyName="http.status" value="500" doc:name="Set http status 500" />
<json:object-to-json-transformer doc:name="Object to JSON" />
</catch-exception-strategy>
</choice-exception-strategy>
</flow> <!--
应用启动时,该流服务随之启动,然后在vm://acquireFlightPriceQueue上等待请求
-->
<flow name="acquireSeatsInfo">
<!-- 在acquireSeatsInfoQueue路径上等待输入座位信息 -->
<vm:inbound-endpoint exchange-pattern="request-response" path="acquireSeatsInfoQueue" doc:name="VM"/> <!-- 使用脚本进行处理 -->
<scripting:component doc:name="Acquire seats info service">
<scripting:script engine="Groovy"><![CDATA[
if (payload.flightNumber.endsWith('2'))
payload.seatInfo = '20A'
else
throw new Exception('No seat info available')
payload]]></scripting:script>
</scripting:component> <!-- 异常处理 -->
<catch-exception-strategy doc:name="Catch Exception Strategy">
<expression-component doc:name="Add no seat info available message"><![CDATA[payload.seatInfo = 'No seat info available']]></expression-component>
</catch-exception-strategy>
</flow> <!-- 如:下面的path="acquireFlightPriceQueue"配置拼写不对
********************************************************************************
Message : There is no receiver registered on connector "connector.VM.mule.default" for endpointUri vm://acquireFlightPriceQueue
Code : MULE_ERROR-0
在端点地址为vm://acquireFlightPriceQueue的连接器上没有注册接收者
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Exception stack is:
1. There is no receiver registered on connector "connector.VM.mule.default" for endpointUri vm://acquireFlightPriceQueue (org.mule.api.transport.NoReceiverForEndpointException)
org.mule.transport.vm.VMMessageDispatcher:85 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/NoReceiverForEndpointException.html)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Root Exception stack trace:
org.mule.api.transport.NoReceiverForEndpointException: There is no receiver registered on connector "connector.VM.mule.default" for endpointUri vm://acquireFlightPriceQueue
at org.mule.transport.vm.VMMessageDispatcher.doSend(VMMessageDispatcher.java:85)
at org.mule.transport.AbstractMessageDispatcher.process(AbstractMessageDispatcher.java:81)
at org.mule.transport.AbstractConnector$DispatcherMessageProcessor.process(AbstractConnector.java:2627)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
航班的票价计算怪怪的,编号*2: payload.ticketPrice = Integer.valueOf(payload.flightNumber) * 2
-->
<flow name="acquireFlightPrice">
<vm:inbound-endpoint exchange-pattern="request-response" path="acquireFlightPriceQueue" doc:name="acquireFlightPrice"/>
<expression-component doc:name="acquireFlightPrice">
<![CDATA[payload.ticketPrice = Integer.valueOf(payload.flightNumber) * 2]]>
</expression-component>
</flow>
</mule>

3 相关类定义

1)Flight -- 航班信息类

 package org.mule.example;

 import java.io.Serializable;

 public class Flight implements Serializable {

     /**
*
*/
private static final long serialVersionUID = -841916700389246787L; private String flightNumber;
private String seatInfo;
private Double ticketPrice; public String getFlightNumber() {
return flightNumber;
} public void setFlightNumber(String flightNumber) {
this.flightNumber = flightNumber;
} public String getSeatInfo() {
return seatInfo;
} public void setSeatInfo(String seatInfo) {
this.seatInfo = seatInfo;
} public Double getTicketPrice() {
return ticketPrice;
} public void setTicketPrice(Double ticketPrice) {
this.ticketPrice = ticketPrice;
}
}

2)ReservationRequest -- 请求消息负载内容类

 package org.mule.example;

 import java.io.Serializable;

 public class ReservationRequest implements Serializable {

     /**
*
*/
private static final long serialVersionUID = 3502244785792589115L; private Flight[] flights; public Flight[] getFlights() {
return flights;
} public void setFlights(Flight[] flights) {
this.flights = flights;
}
}

3)ReservationResponse 响应消息负载内容类

 package org.mule.example;

 import java.io.Serializable;
import java.util.ArrayList;
import java.util.List; public class ReservationResponse implements Serializable { private List<String> errors = new ArrayList<String>(); private Flight[] flights;
public Double totalPrice; public Double getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(Double totalPrice) {
this.totalPrice = totalPrice;
} public List<String> getErrors() {
return errors;
}
public void setErrors(List<String> errors) {
this.errors = errors;
} public Flight[] getFlights() {
return flights;
}
public void setFlights(Flight[] flights) {
this.flights = flights;
} //------ 添加错误信息---------------------
public void addError(String error) {
errors.add(error);
} //------- 原始请求对象---------------------
private ReservationRequest originalRequest; public ReservationRequest getOriginalRequest() {
return originalRequest;
} public void setOriginalRequest(ReservationRequest originalRequest) {
this.originalRequest = originalRequest;
}
}

4)FlightUnavailableException 异常类

 package org.mule.example;

 public class FlightUnavailableException extends Exception {

 }

4 Ajax访问页面

1)index.html

 <!DOCTYPE html>
<html>
<head>
<link href="flight-reservation.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="mule-resource/js/mule.js"></script>
<script type="text/javascript" src="flight-reservation.js"></script>
</head>
<body onload="onload();">
<div class="content">
<div class="flightReservationHeader"> Flight Reservation System </div>
<div id="title"> Search Best Flight </div>
<div class="searchBox">
<form id="searchFlight">
<div class="cities">
<div id="origin">
<div>Origin</div>
<select class="origin" id="originCity">
<option value=""></option>
<option value="BUE">Buenos Aires (BUE)</option>
</select>
</div>
<div id="destination">
<div>Destination</div>
<select class="destination" id="destinationCity">
<option value=""></option>
<option value="MOW">Moscu (MOW) </option>
<option value="HKG">Hong Kong (HKG) </option>
<option value="TW">Tai Wang (TW)</option>
</select>
</div>
</div>
</form>
<div id="makeSearch">
<input id="searchButton" type="button" value="Search" onClick="makeSearch(dojo.byId('originCity').value, dojo.byId('destinationCity').value)">
</div>
</div>
<div class="response">
<div id="error"><div id="errorMessage"></div></div>
<div id="searchResults"></div>
</div>
</div>
</body>
</html>

2) flight-reservation.js

 function onload() {
dojo.byId("error").style.display = "none";
dojo.byId("searchResults").style.display = "none";
} //发送航班请求
function makeSearch(origin, destination) {
var request=""; if (origin == "BUE" && destination == "MOW")
{ var request = {
"flights": [
{"flightNumber":912},
{"flightNumber":1022},
{"flightNumber":732}
]
};
mule.rpc("/searchFlights", JSON.stringify(request), processResponse);
}
else if (origin == "BUE" && destination == "HKG")
{
var request = {
"flights":[
{"flightNumber":822},
{"flightNumber":1133}
]
};
mule.rpc("/searchFlights", JSON.stringify(request), processResponse);
}
else if (origin == "BUE" && destination == "TW")
{
var request = {
"flights":[
{"flightNumber":822},
{"flightNumber":1004}
]
};
mule.rpc("/searchFlights", JSON.stringify(request), processResponse);
}
else
{
var request={"Invalid Request":[]};
mule.rpc("/searchFlights", JSON.stringify(request), processResponse);
}
} //处理响应
function processResponse(message) {
resp = JSON.parse("[" + message.data + "]")[0]; if(resp.errors == "")
{
dojo.byId("error").style.display = "none";
dojo.byId("searchResults").style.display = "block"; var results = "<table class='results'>";
results += "<th>Flight Number</th><th>Seat assignment</th><th>Price</th>" for(var i = 0; i < resp.flights.length;i++)
{
results +="<tr><td>" + resp.flights[i].flightNumber + "</td><td>" + resp.flights[i].seatInfo + "</td><td>$" + resp.flights[i].ticketPrice + "</td></tr>";
} results += "<tr><td colspan='3'><div id='totalPrice'>Total price is $" + resp.totalPrice + "</div></td><tr>"
results += "</table>"; dojo.byId("searchResults").innerHTML = results;
}
else
{
dojo.byId("error").style.display = "block";
dojo.byId("searchResults").style.display = "none";
dojo.byId("errorMessage").innerHTML = resp.errors;
}
}

3) flight-reservation.css

 .content {
padding: 20px 0 20px 50px;
width: 620px;
color: #003399;
background-color: #F8F8FF
} .flightReservationHeader {
text-align: center;
font-weight: bold;
padding-bottom: 20px;
font-size: 1.8em;
} #title {
padding-top: 5px;
font-weight: bold;
background-color: #E8EDFF;
width: 150px;
height: 25px;
border: 2px solid #B9C9FE;
text-align: center
} .searchBox {
width: 550px;
background-color: #E8EDFF;
border: 2px solid #B9C9FE;
position: relative;
padding-bottom: 30px;
padding-top: 20px
} .cities {
padding: 10px 35px 10px 35px
} #origin {
float: left;
padding-right: 50px
} .origin {
width: 215px
} .destination {
width: 215px
} #destination {
float: left
} #makeSearch {
clear: both;
padding: 20px 0 10px 40px;
position: relative;
} #searchButton {
background-color: #B9C9FE
} #error {
width: 550px;
height: 50px;
color: #FF0000;
text-align: center;
background-color: #FFDAB9;
border: 2px solid #FF0000;
display: none
} #errorMessage {
padding: 10px
} .response {
padding-top: 30px
} .response table {
width: 550px;
} .response table th {
background: none repeat scroll 0 0 #B9C9FE;
border-bottom: 1px solid #FFFFFF;
border-top: 4px solid #AABCFE;
color: #003399;
padding: 8px
} .response table td {
background: none repeat scroll 0 0 #E8EDFF;
border-bottom: 1px solid #FFFFFF;
border-top: 1px solid transparent;
color: #666699;
padding: 8px;
} #totalPrice {
float: right;
font-weight: bold
}

5 执行效果分析

1)flights编号都以'2'结尾,所以正常运行

2)该请求包含了一个以'3'结尾的航班编号,触发该航班不可得异常

3)尾号为2的航班,分配的座位都是'20A';尾号为3的航班,不可得;尾号不是2、3的航班没座位

Mule自带例子之flight-reservation的更多相关文章

  1. Mule自带例子之stockquote

    1 配置效果图 2 配置文件 <?xml version="1.0" encoding="UTF-8"?> <mule version=&qu ...

  2. Mule自带例子之loanbroker-simple

    1 配置效果图 2 配置文件 <?xml version="1.0" encoding="UTF-8"?> <mule xmlns:cxf=& ...

  3. Mule ESB 自带例子hello初体验

    1 配置的流的效果图 2 应用配置文件hello.xml内容 <?xml version="1.0" encoding="UTF-8"?> < ...

  4. 可视化工具solo show-----Prefuse自带例子GraphView讲解

    2014.10.15日以来的一个月,挤破了头.跑断了腿.伤透了心.吃够了全国最大餐饮连锁店——沙县小吃.其中酸甜苦辣,绝不是三言两语能够说得清道的明的.校招的兄弟姐妹们,你们懂得…… 体会最深的一句话 ...

  5. MYSQL的锁介绍,以及死锁发生情况-带例子

    mysql锁能在并发情况下的mysql进行更好的优化 MySQL有三种锁的级别:页级.表级.行级,这3种锁的特性可大致归纳如下: 表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生锁冲突的概率最高 ...

  6. hadoop自带例子wordcount的具体运行步骤

    1.在hadoop所在目录“usr/local”下创建一个文件夹input root@ubuntu:/usr/local# mkdir input 2.在文件夹input中创建两个文本文件file1. ...

  7. asp.net web api 2.2 基础框架(带例子)

    链接:https://github.com/solenovex/asp.net-web-api-2.2-starter-template 简介 这个是我自己编写的asp.net web api 2.2 ...

  8. OPENCV SVM介绍和自带例子

    依据机器学习算法如何学习数据可分为3类:有监督学习:从有标签的数据学习,得到模型参数,对测试数据正确分类:无监督学习:没有标签,计算机自己寻找输入数据可能的模型:强化学习(reinforcement ...

  9. Python中threading的join和setDaemon的区别[带例子]

    python的进程和线程经常用到,之前一直不明白threading的join和setDaemon的区别和用法,今天特地研究了一下.multiprocessing中也有这两个方法,同样适用,这里以thr ...

随机推荐

  1. 如何在不卸载原来jdk1.8的情况下切换到jdk1.7

    将Path环境变量中的JAVA_HOME变量中写入现在的JDK1.7路径即可.

  2. Python学习笔记(二)使用Sublime Text编写简单的Python程序()

    一.使用Sublime Text编写Python 1.点击“文件” →”新建文件“ 2.点击”文件“→”保存“,并保存为.py文件 此时已经创建好Python文件了,接下来就可以编写Python程序了 ...

  3. Liferay如何连接本地的数据库

    Liferay自带的数据库非常迷你,一般就是玩玩的. 在真实的开发过程中,我们往往需要把它与我们本地的数据库相连. 有3中方法,我在这里就只介绍我自己最喜欢的方法啦.连的是mysql 1.在Lifer ...

  4. XML配置里的Bean自动装配与Bean之间的关系

    需要在<bean>的autowire属性里指定自动装配的模式 byType(根据类型自动装配) byName(根据名称自动装配) constructor(通过构造器自动装配) 名字须与属性 ...

  5. Web.xml详解(转)(Filter,context,listener)

    web.xml 详细解释!!(链接) web.xml加载过程(步骤) 首先简单说一下,web.xml的加载过程. 当我们去启动一个WEB项目时,容器包括(JBoss.Tomcat等)首先会读取项目we ...

  6. 了解apache与tomcat的关系

    较多的了解过apache,但对tomcat却了解不多: 使用LAMP构建网站毕竟还是有很大局限,越来越多的网站将给予java构建了. http://developer.51cto.com/art/20 ...

  7. 简单的requestAnimationFrame动画

    html部分 <div id="test" style="width:1px;height:17px;background:#0f0;">0%< ...

  8. python 模块的作用

  9. 封装好的PDO类

    封装PDO类,方便使用: <?php header('content-type:text/html;charset=utf-8'); /** * 封装PDODB类 */ // 加载接口 // i ...

  10. 【JZOJ4886】【NOIP2016提高A组集训第13场11.11】字符串

    题目描述 某日mhy12345在教同学们写helloworld,要求同学们用程序输出一个给定长度的字符串,然而发现有些人输出了一些"危险"的东西,所以mhy12345想知道对于任意 ...