Mule自带例子之flight-reservation
阅读原文时间:2023年07月15日阅读:1

1 配置效果图

2 应用的配置文件

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]]>

         <!--  
         此处声明了一个地址为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]]>



         <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]]>






 <!--  
 应用启动时,该流服务随之启动,然后在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]]>

     <!-- 异常处理 -->  
     <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
      -->

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





Flight Reservation System
Search Best Flight



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的航班没座位

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章