天天看點

mule in action翻譯15 : 3.3 使用HTTP傳輸mule in action翻譯15 : 3.3  使用HTTP傳輸3.3  使用HTTP傳輸

mule in action翻譯15 : 3.3  使用HTTP傳輸

3.3  使用HTTP傳輸

    本節講mule對HTTP和web service的支援。對HTTP的支援,使從web站點或應用接受或發送資料變的更簡單。mule支援 JAX-RS和JAX-WS,提供了對REST和SOAP的API支援。

3.3.1 使用HTTP發送和接受資料

    HTTP傳輸允許你使用HTTP協定進行發送和接受資料。你可以通過outbound endpoint使用HTTP的POST方法發送資料,或在請求-響應式的inbound endpoint 以GET傳回傳回資料。表2.3列舉了 HTTP 連接配接器和 endpoint的的一些常用的配置元素。

mule in action翻譯15 : 3.3 使用HTTP傳輸mule in action翻譯15 : 3.3  使用HTTP傳輸3.3  使用HTTP傳輸

     來看如何使用 HTTP outbound endpoint向一個URL發送POST資料。Arnor Accounting公司開發人員同意

了Prancing Donkey公司以 XLS檔案方式上傳支出報表。如果他們還沒使用mule,這将是一個大問題。

他們的開發人員将會删掉一片代碼--拷貝檔案到會計人員目錄的代碼,而替換為以POST 方式把檔案内容

發送到遠端的URL.

使用mule 他們隻需要簡單的改變outbound endpoint,像如下清單以及圖3.6所示。

Listing 3.2 Posting data with the HTTP transport

<flow name="postExpenseReports">
    <file:inbound-endpoint path="./data/expenses/2/in"
               pollingFrequency="60000">
    <file:filename-regex-filter pattern=".*xls$"
                          caseSensitive="false"/>
    </file:inbound-endpoint>
    <--!使用HTTP endpoint把支出報表POST出去-->
    <http:outbound-endpoint host="${http.host}"
                            port="${http.port}"
                            path="expenseReports"
                          method="POST"/>
</flow>      
mule in action翻譯15 : 3.3 使用HTTP傳輸mule in action翻譯15 : 3.3  使用HTTP傳輸3.3  使用HTTP傳輸

    把file:outbound-endpoint 替換為  http:outbound-endpoint就夠了。資料不再需要寫向檔案,而是需要發送到遠端web應用。

   使用一個HTTP作為一個消息是相當容易的。既然處理支出檔案會花費一些時間,那麼 SaaS應用可以異步的處理檔案。Arnor Accounting的開發人員已經添加了一個功能:當報表被處理完成後會向一個特定的URL發送一個通知。現在  Prancing Donkey公司想接收這個通知并寫入到檔案系統,之後監控系統可以解析其中的錯誤。(你将這在3.4節是如何改進的)。

下面清單說明了如何配置,圖3.7是圖形化表示

Listing 3.3 Using an HTTP inbound endpoint to POST data to a file 

<flow name="expenseReportCallback">
<!--注釋1  在 http://${http.host}/expenses/status   接收HTTP請求-->
<http:inbound-endpoint host="${http.host}"
                      port="${http.port}"
                      path="expenseReportCallback"
                    method="POST"
          exchange-pattern="one-way"/>

<!--注釋2   把支出報表處理狀态寫到 ./data/expenses/status 目錄-->
<file:outbound-endpoint path="./data/expenses/status"
               outputPattern="#[java.util.UUID.randomUUID().toString()]
                               -#[org.mule.util.DateUtils.getTimeStamp
                               ('dd-MM-yy_HH-mm-ss.SSS')]
                         .xml"/>

</flow>      
mule in action翻譯15 : 3.3 使用HTTP傳輸mule in action翻譯15 : 3.3  使用HTTP傳輸3.3  使用HTTP傳輸

    注釋1處  配置的HTTP inbound endpoint 接收HTTP POST請求,将包含狀态通知。

這些傳送的payload 将被寫到配置的目錄中。注意之前的流和目前的流,都使用的是 單向交換方式。

這允許你使用HTTP模拟異步請求,但HTTP是一個同步協定。本案例中,mule将傳回 200 OK的響應給

用戶端,除非流跑出了異常。第9章你會看到異常處理。

  HTTPS   你将看到的所有的HTTP例子都是預設的未加密的。第10章讨論HTTPS 和 SSL .

  異步處理HTTP請求是一個有用的技術。它允許你通過HTTP實作消息的API.

  你處理最多的HTTP請求還是請求-響應式的。

  3.3.2 mule使用 web services 

      Prancing Donkey公司有一個叫做BrewService的服務類,開發人員想他它暴露給外部用戶端使用。

  這個服務目前一個方法 getBrews(),它會傳回前的啤酒清單。這個方法傳回一個List, list的每個元素是一  個Brew的執行個體--這是他們域模型的一部分。清單 3.4 、3.5 、3.6詳細  列出了BrewService接口和實作以及域  模型類Brew.

  JAX-RS AND JAX-WS   本節的例子中将使用JAX-RS 和 JAX-WS标準,對這兩個标準的讨論

      超出了本書的範疇。要了解其詳細資訊,包括怎樣在模型類使用注解控制序列化,

 請參考 http://jersey.java.net  和 http://cxf.apache.org/ 。

  Listing 3.4 The BrewService interface

package com.prancingdonkey.service;
public interface BrewService {
    List<Brew> getBrews();
}  
           

Listing 3.5 The BrewService implementation

package com.prancingdonkey.service;
public class BrewServiceImpl implements BrewService {
    List<Brew> getBrews() {
       return Brew.findAll();
    }
}
           

Listing 3.6 The Brew domain model

package com.prancingdonkey.model;
public class Brew implements Serializable {
    String name;
    String description;
    public Brew(String name, String description) {
        this.name = name;
        this.description = description;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    static public List<Brew> findAll()
    {
       // Returns a List of Brews
        return ...
     }
}
           

  我們現在看如何使用REST和SOAP暴露getBrews() 方法給外部使用者。

REST 和  JAX-RS

    JAX-RS是 RESTful風格的web service 的java API。mule支援Jersey,它是JAX-RS的一個實作,允許你在mule流中使用JAX-RS注解開發RESTfull風格的web service。來注解BrewServiceImpl以JSON 方式傳回啤酒目錄。

Listing 3.7 The JAX-RS annotated BrewService

package com.prancingdonkey.service;
@Path("/brews")  //注釋1 URI路徑的root
public class BrewServiceImpl implements BrewService {

    @GET  //注釋2  接受的 HTTP 方法
    @Produces("application/json")  //注釋3  方法的傳回值類型
    List<Brew> getBrews() {

      return Brew.findAll();
    }
}
           

  注釋1 處  @Path注解指定了本類中你暴露的方法的根URI(你也可以在方法上指定@Path來

                  進一步限定路徑)

  注釋2處  @GET注解指明這個方法隻對HTTP GET請求進行響應。

  注釋3處  @Produces注解表明将傳回JSON格式的響應。

  現在BrewServiceImpl已别注解好,來把它放到流中。下面的清單說明了如何在流中配置。

Mule studio中圖見 圖3.8

Listing 3.8 Expose the brew listing over REST using JAX-RS 

<flow name="brewRestService">
<!--注釋1  HTTP inbound endpoint接受REST請求-->
<http:inbound-endpoint address="http://localhost:8091/rest"
exchange-pattern="request-response"/>
<jersey:resources>
<!--注釋2  要暴露為Jersey資源的類-->
<component class="com.prancingdonkey.service.BrewServiceImpl"/>
</jersey:resources>
</flow>
      
mule in action翻譯15 : 3.3 使用HTTP傳輸mule in action翻譯15 : 3.3  使用HTTP傳輸3.3  使用HTTP傳輸

注釋1處  設定攔截RESTfull請求。

注釋2處  暴露注釋的JAX-RS類

現在你可以啟動mule,執行你的請求了。

來使用curl調用下這個服務看看會發生什麼。

Listing 3.9 Using curl to invoke the web service

% curl

http://api.prancingdonkey.com/rest/brews/list

[ {"name":"Frodo's IPA", "description":"Indian Pale Ale" }, {

"name":"Bilbo's Lager", "description":"Indian Pale Ale" }, {

"name":"Gandalf's Barley Wine", "description":"Indian Pale Ale" } ]

curl對 rest/brews/list URI的請求傳回 方法的響應,元素時Brew的list,序列化為JSON.

你可以通過JAXB定制如何生存JSON.

現在來看 如何根據mule對JAX-WS的支援把同樣的服務暴露為SOAP方式通路的服務。

調用 REST 服務的工具   Curl是一個可以用來與REST 服務進行互動的指令行工具。

可以在 http://curl.haxx.se/ 進行下載下傳。另外一個強大的工具是 google chrome浏覽器

的 REST  Console。可用chrome連接配接http://restconsole.com. 安裝。

SOAP 和 JAX-WS 以及 APACHE CXF 

    JAX-WS是java 對 xml web service 的API 。JAX-WS提供了一系列的注解來簡化 SOAP驅動的

 web service的開發。 Mule通過apache的CXF支援JAX-WS. 要BrewService為可用通 SOAP方式

 通路,你需要注解實作類 BrewServiceImpl ,就像你使用JAX-RS時一樣。你也需要抽出并注解

 一個接口--BrewService。

  APACHE CXF  APACHE CXF是一個建構web service的開源架構。mule多數對SOAP的支援通過使用

          APACHE CXF實作。 CXF是一個非常強大 ,而且比較複雜,對它的讨論超出的本書的範圍。

         讀者去http://cxf.apache.org/docs/index.html 檢視使用者手冊。

 CXF使用接口生成 web service 的 WSDL。這是用戶端連接配接的契約。

清單 3.10 和 3.11 展示了如何注解 BrewService和 BrewServiceImpl以生成WSDL以及

如何注解實作類。

Listing 3.10 The JAX-WS annotated BrewService interface 

package com.prancingdonkey.service;
@WebService
public interface BrewService {
   List<Brew> getBrews();
}  
           

Listing 3.11 The JAX-WS annotated BrewService implementation 

package com.prancingdonkey.service;
@WebService(endpointInterface ="com.prancingdonkey.service.BrewService",
                  serviceName = "BrewService")
public class BrewServiceImpl implements BrewService {
    List<Brew> getBrews() {
        return Brew.findAll();
    }
}
           

現在把 SOAP串聯在mule中 。和Jersey類似 見下清單以及 圖 3.9

Listing 3.12 Expose the brew listing over SOAP using CXF 

<flow name="brewSoapService">
<!--注釋1   HTTP endpoint接受SOAP請求-->
<http:inbound-endpoint address="http://localhost:8090/soap"
exchange-pattern="request-response"/>

<cxf:simple-service
<!-- 要暴露的服務接口-->
serviceClass="com.prancingdonkey.service.BrewService"/>
<!--實作類-->
<component class="com.prancingdonkey.service.BrewServiceImpl"/>
</flow>
      
mule in action翻譯15 : 3.3 使用HTTP傳輸mule in action翻譯15 : 3.3  使用HTTP傳輸3.3  使用HTTP傳輸

web service的位址是http://api.prancingdonkey.com/soap?wsdl

來使用 SOAPUI用戶端,指向這個WSDL并生成請求,看到傳回才響應如圖 3.10 。

3.10 圖左邊部分顯示了 WSDL的操作,本例中隻有一個 getBrews。

點選左邊的 getBrews 将生成一個簡單的請求如圖中間部分。

點選綠色的運作按鈕,将發送請求到mule,并會在圖右側部分顯示響應。

mule in action翻譯15 : 3.3 使用HTTP傳輸mule in action翻譯15 : 3.3  使用HTTP傳輸3.3  使用HTTP傳輸

Figure 3.10   Using SOAP UI to invoke the SOAP service

JAXB  你可以使用 JAXB控制CXF和 Jersey的序列化。更多細節參看 http://jaxb.java.net/tutorial/

CXF也可以用來調用web service 。假設Arnor Accounting提供了一個WSDL 描述他們的 SAOP API .

你可以把清單3.1 的流修改為通過這種機制送出支援報表,如下所示:

Listing 3.13 Submit expense reports using SOAP

<flow name="brewListingOverSOAP">
<file:inbound-endpoint path="/data/expenses/in"
pollingFrequency="60000"/>
<cxf:jaxws-client
<!--注釋1  CXF生成的用戶端類-->
clientClass="com.arnor.api.AccountingService"
<!--注釋2  WSDL端口-->
wsdlPort="SoapPort"
<!--注釋3  WSDL位置-->
wsdlLocation="classpath:/wsdl/services.wsdl"
<!--注釋4  要調用的操作-->
operation="submitExpenses"/>
</flow>      

 采用CXF的wsdl2java生成用戶端類後 ,就可以使用mule調用web service了。

 生成的類配置在注釋1處。WSDL的端口和位置配置定義在注釋2和注釋3處。

 調用的操作在注釋4處。

 在本節機學習了如何使用HTTP 調換資料。你看mule的HTTP如何傳輸可以發送和接受消息,

 以及如何進行異步HTTP請求的處理。你看到了依據mule對JAX-RS 和JAX-WS的支援來暴露使用

 REST和SOAP方式通路的服務。

 簡單服務模式   你将在第6章看到簡單服務方式可以用來把POJO暴露為REST和SOAP通路的服務,

               這僅僅隻需要一行配置。如果你的服務很簡單 ,或者你沒必要使用JAX-RS 及 JAX-WS标準的話這

              種方式可能更合理。

繼續閱讀