• Mule自带例子之flight-reservation


    1 配置效果图

    2 应用的配置文件

      1 <?xml version="1.0" encoding="UTF-8"?>
      2 
      3 <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"
      4     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"
      5     xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      6     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
      7 http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
      8 http://www.mulesoft.org/schema/mule/ajax http://www.mulesoft.org/schema/mule/ajax/current/mule-ajax.xsd
      9 http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
     10 http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
     11 http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd">
     12 
     13 
     14     <ajax:connector name="Ajax" serverUrl="http://0.0.0.0:9092/reservation" resourceBase="${app.home}/docroot" jsonCommented="true"    doc:name="Ajax" />
     15 
     16     <!-- 航班预定流,主要通过调用processReservation来完成航班信息的处理 -->
     17     <flow name="makeReservation">
     18         <ajax:inbound-endpoint channel="/searchFlights" connector-ref="Ajax" responseTimeout="10000" doc:name="Ajax" />
     19         <flow-ref name="processReservation" doc:name="processReservation"/>
     20     </flow>
     21 
     22     
     23     <!-- 
     24     航班预定信息处理流
     25         对航班的安排做的假设:
     26             航班号以3结尾,不可获得,直接抛出FlightUnavailableException异常
     27             航班号不是以3结尾,可进入下一步处理:
     28                 航班号以2结尾,可取得座位信息'20A';否则抛出没有座位信息异常'No seat info available',并把'No seat info available'赋给座位信息部分            
     29      -->
     30     <flow name="processReservation">
     31     
     32         <json:json-to-object-transformer returnClass="org.mule.example.ReservationRequest" doc:name="JSON to ReservationRequest" />    
     33         
     34         <!-- 把请求的负载保存到session对象中(payload的类型为ReservationRequest) -->
     35         <set-session-variable variableName="reservationRequest" value="#[payload]" doc:name="Save orignal request in Session" />
     36         
     37         <!-- 设置响应消息的负载 -->
     38         <set-payload value="#[new org.mule.example.ReservationResponse()]" doc:name="Set ReservationResponse Payload" />
     39         
     40         <!-- 把请求消息中的flighs设置到响应消息中 (payload的类型为ReservationResponse) -->
     41         <expression-component doc:name="Add request flight to response">
     42             <![CDATA[payload.setFlights(reservationRequest.flights)]]>
     43         </expression-component>
     44         
     45         <set-variable variableName="totalPrice" value="#[0]" doc:name="Initialize totalPrice" /> <!-- 设置一个totalPrice变量,值为0 -->
     46         
     47         <!-- 迭代处理payload(payload的类型为ReservationResponse,里面有请求信息flights) -->
     48         <foreach collection="#[payload.flights]" doc:name="Foreach on flights">
     49             <scripting:transformer doc:name="Search flight availability">
     50                 <scripting:script engine="Groovy"><![CDATA[
     51 if (payload.flightNumber.endsWith('3'))
     52     throw new org.mule.example.FlightUnavailableException()
     53 else
     54     payload]]>
     55                 </scripting:script>
     56             </scripting:transformer>
     57             
     58             <!-- 
     59             此处声明了一个地址为vm://acquireFlightPriceQueue VM出站端点,即把响应消息扔到了acquireSeatsInfoQueue队列
     60             而acquireSeatsInfo流,在地址vm://acquireFlightPriceQueue上等待请求
     61             exchange-pattern="request-response" 表示该VM出站端点 等待acquireSeatsInfo流给的响应
     62             -->
     63             <vm:outbound-endpoint exchange-pattern="request-response" path="acquireSeatsInfoQueue" doc:name="Acquire Seats Info"/>
     64             <!-- 再把响应消息扔到了acquireFlightPriceQueue队列,等待响应 -->
     65             <vm:outbound-endpoint exchange-pattern="request-response" path="acquireFlightPriceQueue" doc:name="Acquire Flight Price" />
     66             
     67             <!-- 更新totalPrice变量的值,把本次迭代的票价加到总价中 -->
     68             <set-variable variableName="totalPrice" value="#[totalPrice + payload.ticketPrice]" doc:name="Add price to totalPrice" />
     69         </foreach>
     70         
     71         <expression-component doc:name="Add total price to reservation">
     72             <![CDATA[payload.totalPrice = flowVars['totalPrice']]]>
     73         </expression-component>
     74         <!-- 把响应对象转换为JSON, 航班预定处理结束 -->
     75         <json:object-to-json-transformer doc:name="Object to JSON" />
     76         
     77         
     78         <!-- 异常捕获区 -->
     79         <choice-exception-strategy doc:name="Choice Exception Strategy">    
     80             <!--  -->
     81             <catch-exception-strategy when="#[exception.causedBy(org.mule.example.FlightUnavailableException)]" doc:name="Catch Exception Strategy">
     82                 <scripting:transformer doc:name="Add no avaiilability error">
     83                     <scripting:script engine="Groovy">
     84                         <![CDATA[
     85 def payload = new org.mule.example.ReservationResponse()
     86 payload.addError('There is no availability for the selected flight!')
     87 payload]]>
     88                     </scripting:script>
     89                 </scripting:transformer>
     90                 <json:object-to-json-transformer doc:name="Object to JSON" />
     91             </catch-exception-strategy>
     92             
     93             <catch-exception-strategy doc:name="Catch Exception Strategy">
     94                 <scripting:transformer doc:name="Add exception message">
     95                     <scripting:script engine="Groovy">
     96                         <![CDATA[                  
     97 def payload = new org.mule.example.ReservationResponse()
     98 payload.addError('Error processing request!')
     99 payload]]>
    100                     </scripting:script>
    101                 </scripting:transformer>
    102                 <set-property propertyName="http.status" value="500" doc:name="Set http status 500" />
    103                 <json:object-to-json-transformer doc:name="Object to JSON" />
    104             </catch-exception-strategy>
    105         </choice-exception-strategy>
    106     </flow>
    107     
    108     <!-- 
    109     应用启动时,该流服务随之启动,然后在vm://acquireFlightPriceQueue上等待请求
    110      -->
    111     <flow name="acquireSeatsInfo">
    112         <!-- 在acquireSeatsInfoQueue路径上等待输入座位信息 -->
    113         <vm:inbound-endpoint exchange-pattern="request-response" path="acquireSeatsInfoQueue" doc:name="VM"/>
    114         
    115         <!-- 使用脚本进行处理 -->
    116         <scripting:component doc:name="Acquire seats info service">
    117             <scripting:script engine="Groovy"><![CDATA[
    118 if (payload.flightNumber.endsWith('2'))
    119     payload.seatInfo = '20A'
    120 else
    121     throw new Exception('No seat info available')
    122 payload]]></scripting:script>
    123         </scripting:component>
    124         
    125         <!-- 异常处理 -->
    126         <catch-exception-strategy doc:name="Catch Exception Strategy">
    127             <expression-component doc:name="Add no seat info available message"><![CDATA[payload.seatInfo = 'No seat info available']]></expression-component>    
    128         </catch-exception-strategy>
    129     </flow>
    130     
    131     
    132     <!-- 
    133     
    134     如:下面的path="acquireFlightPriceQueue"配置拼写不对
    135 ********************************************************************************
    136 Message               : There is no receiver registered on connector "connector.VM.mule.default" for endpointUri vm://acquireFlightPriceQueue
    137 Code                  : MULE_ERROR-0
    138 在端点地址为vm://acquireFlightPriceQueue的连接器上没有注册接收者
    139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    140 Exception stack is:
    141 1. There is no receiver registered on connector "connector.VM.mule.default" for endpointUri vm://acquireFlightPriceQueue (org.mule.api.transport.NoReceiverForEndpointException)
    142   org.mule.transport.vm.VMMessageDispatcher:85 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/NoReceiverForEndpointException.html)
    143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    144 Root Exception stack trace:
    145 org.mule.api.transport.NoReceiverForEndpointException: There is no receiver registered on connector "connector.VM.mule.default" for endpointUri vm://acquireFlightPriceQueue
    146     at org.mule.transport.vm.VMMessageDispatcher.doSend(VMMessageDispatcher.java:85)
    147     at org.mule.transport.AbstractMessageDispatcher.process(AbstractMessageDispatcher.java:81)
    148     at org.mule.transport.AbstractConnector$DispatcherMessageProcessor.process(AbstractConnector.java:2627)
    149     + 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
    150 ********************************************************************************
    151     航班的票价计算怪怪的,编号*2: payload.ticketPrice = Integer.valueOf(payload.flightNumber) * 2
    152      -->
    153     <flow name="acquireFlightPrice">
    154         <vm:inbound-endpoint exchange-pattern="request-response" path="acquireFlightPriceQueue" doc:name="acquireFlightPrice"/>   
    155         <expression-component doc:name="acquireFlightPrice">
    156             <![CDATA[payload.ticketPrice = Integer.valueOf(payload.flightNumber) * 2]]>
    157         </expression-component>
    158     </flow>
    159 </mule>

    3 相关类定义

    1)Flight -- 航班信息类

     1 package org.mule.example;
     2 
     3 import java.io.Serializable;
     4 
     5 public class Flight implements Serializable {
     6 
     7     /**
     8      * 
     9      */
    10     private static final long serialVersionUID = -841916700389246787L;
    11 
    12     private String flightNumber;
    13     private String seatInfo;
    14     private Double ticketPrice;
    15 
    16     public String getFlightNumber() {
    17         return flightNumber;
    18     }
    19 
    20     public void setFlightNumber(String flightNumber) {
    21         this.flightNumber = flightNumber;
    22     }
    23 
    24     public String getSeatInfo() {
    25         return seatInfo;
    26     }
    27 
    28     public void setSeatInfo(String seatInfo) {
    29         this.seatInfo = seatInfo;
    30     }
    31 
    32     public Double getTicketPrice() {
    33         return ticketPrice;
    34     }
    35 
    36     public void setTicketPrice(Double ticketPrice) {
    37         this.ticketPrice = ticketPrice;
    38     }
    39 }

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

     1 package org.mule.example;
     2 
     3 import java.io.Serializable;
     4 
     5 public class ReservationRequest implements Serializable {
     6     
     7     /**
     8      * 
     9      */
    10     private static final long serialVersionUID = 3502244785792589115L;
    11     
    12     private Flight[] flights;
    13     
    14     public Flight[] getFlights() {
    15         return flights;
    16     }
    17     
    18     public void setFlights(Flight[] flights) {
    19         this.flights = flights;
    20     }
    21 }

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

     1 package org.mule.example;
     2 
     3 import java.io.Serializable;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 public class ReservationResponse implements Serializable {
     8     
     9     private List<String> errors = new ArrayList<String>();
    10     
    11     private Flight[] flights;
    12     public Double totalPrice;
    13     
    14     
    15     public Double getTotalPrice() {
    16         return totalPrice;
    17     }
    18     public void setTotalPrice(Double totalPrice) {
    19         this.totalPrice = totalPrice;
    20     }
    21 
    22     public List<String> getErrors() {
    23         return errors;
    24     }
    25     public void setErrors(List<String> errors) {
    26         this.errors = errors;
    27     }
    28 
    29     public Flight[] getFlights() {
    30         return flights;
    31     }
    32     public void setFlights(Flight[] flights) {
    33         this.flights = flights;
    34     }
    35     
    36     //------ 添加错误信息---------------------
    37     public void addError(String error) {
    38         errors.add(error);
    39     }
    40     
    41     //------- 原始请求对象---------------------
    42     private ReservationRequest originalRequest;
    43 
    44 
    45     public ReservationRequest getOriginalRequest() {
    46         return originalRequest;
    47     }
    48 
    49     public void setOriginalRequest(ReservationRequest originalRequest) {
    50         this.originalRequest = originalRequest;
    51     }
    52 }

    4)FlightUnavailableException 异常类

    1 package org.mule.example;
    2 
    3 public class FlightUnavailableException extends Exception {
    4 
    5 }

    4 Ajax访问页面

    1)index.html

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <link href="flight-reservation.css" rel="stylesheet" type="text/css"/>
     5     <script type="text/javascript" src="mule-resource/js/mule.js"></script>
     6     <script type="text/javascript" src="flight-reservation.js"></script>
     7 </head>
     8 <body onload="onload();">
     9 <div class="content">
    10     <div class="flightReservationHeader"> Flight Reservation System </div>
    11     <div id="title"> Search Best Flight </div>
    12     <div class="searchBox">
    13         <form id="searchFlight">
    14             <div class="cities">
    15                 <div id="origin">
    16                     <div>Origin</div>
    17                     <select class="origin" id="originCity">
    18                         <option value=""></option>
    19                         <option value="BUE">Buenos Aires (BUE)</option>
    20                     </select>
    21                 </div>
    22                 <div id="destination">
    23                     <div>Destination</div>
    24                     <select class="destination" id="destinationCity">
    25                         <option value=""></option>
    26                         <option value="MOW">Moscu (MOW) </option>
    27                         <option value="HKG">Hong Kong (HKG) </option>
    28                         <option value="TW">Tai Wang (TW)</option>
    29                     </select>
    30                 </div>
    31             </div>
    32         </form>
    33         <div id="makeSearch">
    34             <input id="searchButton" type="button" value="Search" onClick="makeSearch(dojo.byId('originCity').value, dojo.byId('destinationCity').value)">
    35         </div>
    36     </div>
    37     <div class="response">
    38         <div id="error"><div id="errorMessage"></div></div>
    39         <div id="searchResults"></div>
    40     </div>
    41 </div>
    42 </body>
    43 </html>

    2) flight-reservation.js

     1 function onload() {
     2     dojo.byId("error").style.display = "none";
     3     dojo.byId("searchResults").style.display = "none";
     4 }
     5 
     6 //发送航班请求
     7 function makeSearch(origin, destination) {
     8     var request="";
     9         
    10     if (origin == "BUE" && destination == "MOW") 
    11     {
    12         
    13         var request = {
    14                 "flights": [
    15                         {"flightNumber":912},
    16                         {"flightNumber":1022},
    17                         {"flightNumber":732}
    18                            ]
    19                     };
    20         mule.rpc("/searchFlights", JSON.stringify(request), processResponse);    
    21     } 
    22     else if (origin == "BUE" && destination == "HKG") 
    23     {
    24         var request = {
    25                 "flights":[
    26                         {"flightNumber":822},
    27                         {"flightNumber":1133}
    28                           ]
    29                     };
    30         mule.rpc("/searchFlights", JSON.stringify(request), processResponse);
    31     } 
    32     else if (origin == "BUE" && destination == "TW")
    33     {
    34         var request = {
    35                 "flights":[
    36                         {"flightNumber":822},
    37                         {"flightNumber":1004}
    38                           ]
    39                     };
    40         mule.rpc("/searchFlights", JSON.stringify(request), processResponse);
    41     }
    42     else 
    43     {
    44         var request={"Invalid Request":[]};
    45         mule.rpc("/searchFlights", JSON.stringify(request), processResponse);
    46     }
    47 }
    48 
    49 
    50 //处理响应
    51 function processResponse(message) {
    52     resp = JSON.parse("[" + message.data + "]")[0];
    53     
    54     if(resp.errors == "") 
    55     {
    56         dojo.byId("error").style.display = "none";
    57         dojo.byId("searchResults").style.display = "block";
    58 
    59         var results = "<table class='results'>";
    60         results += "<th>Flight Number</th><th>Seat assignment</th><th>Price</th>"
    61         
    62         for(var i = 0; i < resp.flights.length;i++) 
    63         {
    64             results +="<tr><td>" + resp.flights[i].flightNumber + "</td><td>" + resp.flights[i].seatInfo + "</td><td>$" + resp.flights[i].ticketPrice + "</td></tr>";
    65         }
    66         
    67         results += "<tr><td colspan='3'><div id='totalPrice'>Total price is $" + resp.totalPrice + "</div></td><tr>"
    68         results += "</table>";
    69 
    70         dojo.byId("searchResults").innerHTML = results;
    71     } 
    72     else 
    73     {
    74         dojo.byId("error").style.display = "block";
    75         dojo.byId("searchResults").style.display = "none";
    76         dojo.byId("errorMessage").innerHTML = resp.errors;
    77     }
    78 }

    3) flight-reservation.css

      1 .content {
      2     padding: 20px 0 20px 50px;
      3     width: 620px;
      4     color: #003399;
      5     background-color: #F8F8FF
      6 }
      7 
      8 .flightReservationHeader {
      9     text-align: center;
     10     font-weight: bold;
     11     padding-bottom: 20px;
     12     font-size: 1.8em;
     13 }
     14 
     15 #title {
     16     padding-top: 5px;
     17     font-weight: bold;
     18     background-color: #E8EDFF;
     19     width: 150px;
     20     height: 25px;
     21     border: 2px solid #B9C9FE;
     22     text-align: center
     23 }
     24 
     25 .searchBox {
     26     width: 550px;
     27     background-color: #E8EDFF;
     28     border: 2px solid #B9C9FE;
     29     position: relative;
     30     padding-bottom: 30px;
     31     padding-top: 20px
     32 }
     33 
     34 .cities {
     35     padding: 10px 35px 10px 35px
     36 }
     37 
     38 #origin {
     39     float: left;
     40     padding-right: 50px
     41 }
     42 
     43 .origin {
     44     width: 215px
     45 }
     46 
     47 .destination {
     48     width: 215px
     49 }
     50 
     51 #destination {
     52     float: left
     53 }
     54 
     55 #makeSearch {
     56     clear: both;
     57     padding: 20px 0 10px 40px;
     58     position: relative;
     59 }
     60 
     61 #searchButton {
     62     background-color: #B9C9FE
     63 }
     64 
     65 #error {
     66     width: 550px;
     67     height: 50px;
     68     color: #FF0000;
     69     text-align: center;
     70     background-color: #FFDAB9;
     71     border: 2px solid #FF0000;
     72     display: none
     73 }
     74 
     75 #errorMessage {
     76     padding: 10px
     77 }
     78 
     79 .response {
     80     padding-top: 30px
     81 }
     82 
     83 .response table {
     84     width: 550px;
     85 }
     86 
     87 .response table th {
     88     background: none repeat scroll 0 0 #B9C9FE;
     89     border-bottom: 1px solid #FFFFFF;
     90     border-top: 4px solid #AABCFE;
     91     color: #003399;
     92     padding: 8px
     93 }
     94 
     95 .response table td {
     96     background: none repeat scroll 0 0 #E8EDFF;
     97     border-bottom: 1px solid #FFFFFF;
     98     border-top: 1px solid transparent;
     99     color: #666699;
    100     padding: 8px;
    101 }
    102 
    103 #totalPrice {
    104     float: right;
    105     font-weight: bold
    106 }

    5 执行效果分析

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

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

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

  • 相关阅读:
    Android studio 中国的垃圾问题解决
    实现一个简单的boot
    代理下载android4.4源代码
    《程序员在第一季度追姐姐的书》——提升自己的形象气质
    第46周四
    Spring单例与线程安全小结
    2014第46周二
    第46周一
    第45周日
    第45周六
  • 原文地址:https://www.cnblogs.com/asnjudy/p/4593593.html
Copyright © 2020-2023  润新知