日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

把 SOAP 服务转化为 REST 服务(REST Service 的最佳实践,第 3 部分)

發(fā)布時間:2025/7/25 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 把 SOAP 服务转化为 REST 服务(REST Service 的最佳实践,第 3 部分) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

from: https://www.ibm.com/developerworks/cn/webservices/1102_mace_restservicePart3/1102_mace_restservicePart3.html?ca=drs-

基于 SOAP 的 Web 服務和 REST 服務的描述

在本系列的前兩篇文章中,作者系統(tǒng)的介紹了 REST 服務的核心概念以及 REST 和 SOAP 服務的實現機理。接下來,我們以獲取股價的 Web 服務為例,來看看基于 SOAP 的 Web 服務和 REST 服務的描述、發(fā)送請求的方式和響應的格式的不同。

清單 1 所示是一個獲取股價的基于 SOAP 協(xié)議的 Web 服務。如果不熟悉 WSDL 規(guī)范的朋友請參考文獻,我們這里不再詳述。描述文件看起來很復雜,其實就是兩個服務端點,在 service 元素里面描述的兩個:StockQuoteSoap、StockQuoteHttpGet。StockQuoteSoap 說明這個服務端點接受 SOAP 協(xié)議的的請求并在 SOAP body 里面返回服務的結果。StockQuoteHttpGet 是以 SOAP over HTTP 的方式提供服務。另外還有對端口類型、綁定、消息、輸入參數、輸出參數的描述,有點像對一個函數簽名的詳細描述。

清單 1.WSDL 描述的獲取股價的 Web 服務
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 <?xml version="1.0" encoding="utf-8"?> <wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" ?xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" ?xmlns:tns="http://www.webserviceX.NET/" ?xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" ?xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" ?targetNamespace="http://www.webserviceX.NET/" ?xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> ?<wsdl:types> ???<s:schema elementFormDefault="qualified" ???targetNamespace="http://www.webserviceX.NET/"> ?????<s:element name="GetQuote"> ???????<s:complexType> ?????????<s:sequence> ???????????<s:element minOccurs="0" maxOccurs="1" ???????????name="symbol" type="s:string" /> ?????????</s:sequence> ???????</s:complexType> ?????</s:element> ?????<s:element name="GetQuoteResponse"> ???????<s:complexType> ?????????<s:sequence> ???????????<s:element minOccurs="0" maxOccurs="1" ????????????name="GetQuoteResult" type="s:string" /> ?????????</s:sequence> ???????</s:complexType> ?????</s:element> ?????<s:element name="string" nillable="true" type="s:string" /> ???</s:schema> ?</wsdl:types> ?<wsdl:message name="GetQuoteSoapIn"> ???<wsdl:part name="parameters" element="tns:GetQuote" /> ?</wsdl:message> ?<wsdl:message name="GetQuoteSoapOut"> ???<wsdl:part name="parameters" element="tns:GetQuoteResponse" /> ?</wsdl:message> ?<wsdl:message name="GetQuoteHttpGetIn"> ???<wsdl:part name="symbol" type="s:string" /> ?</wsdl:message> ?<wsdl:message name="GetQuoteHttpGetOut"> ???<wsdl:part name="Body" element="tns:string" /> ?</wsdl:message> ?<wsdl:portType name="StockQuoteSoap"> ???<wsdl:operation name="GetQuote"> ?????<documentation xmlns ?????="http://schemas.xmlsoap.org/wsdl/">Get Stock quote for a company Symbol ?????</documentation> ?????<wsdl:input message="tns:GetQuoteSoapIn" /> ?????<wsdl:output message="tns:GetQuoteSoapOut" /> ???</wsdl:operation> ?</wsdl:portType> ?<wsdl:portType name="StockQuoteHttpGet"> ???<wsdl:operation name="GetQuote"> ?????<documentation xmlns ?????="http://schemas.xmlsoap.org/wsdl/">Get Stock quote for a company Symbol ?????</documentation> ?????<wsdl:input message="tns:GetQuoteHttpGetIn" /> ?????<wsdl:output message="tns:GetQuoteHttpGetOut" /> ???</wsdl:operation> ?</wsdl:portType> ?<wsdl:binding name="StockQuoteSoap" type="tns:StockQuoteSoap"> ???<soap:binding transport="http://schemas.xmlsoap.org/soap/http" ????style="document" /> ???<wsdl:operation name="GetQuote"> ?????<soap:operation soapAction="http://www.webserviceX.NET/GetQuote" ?????style="document" /> ?????<wsdl:input> ???????<soap:body use="literal" /> ?????</wsdl:input> ?????<wsdl:output> ???????<soap:body use="literal" /> ?????</wsdl:output> ???</wsdl:operation> ?</wsdl:binding> ?<wsdl:binding name="StockQuoteHttpGet" type="tns:StockQuoteHttpGet"> ???<http:binding verb="GET" /> ???<wsdl:operation name="GetQuote"> ?????<http:operation location="/GetQuote" /> ?????<wsdl:input> ???????<http:urlEncoded /> ?????</wsdl:input> ?????<wsdl:output> ???????<mime:mimeXml part="Body" /> ?????</wsdl:output> ???</wsdl:operation> ?</wsdl:binding> ?<wsdl:service name="StockQuote"> ???<wsdl:port name="StockQuoteSoap" binding="tns:StockQuoteSoap"> ?????<soap:address location="http://www.webservicex.net/stockquote.asmx" /> ???</wsdl:port> ???<wsdl:port name="StockQuoteHttpGet" binding="tns:StockQuoteHttpGet"> ?????<http:address location="http://www.webservicex.net/stockquote.asmx" /> ???</wsdl:port> ???</wsdl:service> </wsdl:definitions>

根據這個服務的描述,我們來看一下怎么調用這個服務。清單 2 和清單 3 給出了調用示例和響應示例。根據描述我們知道,SOAPAction 是 GetQuote,HTTP method 是 GET,這個服務的輸入參數是一個 String 類型的股票代碼,如 IBM,參數名稱是 symbol,服務的端點是 www.webservicex.net/stockquote.asmx。首先如清單 2 所示構建 StockQuoteHttpGet 服務的請求。

清單 2. A SOAP Request 示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 GET /stockquote.asmx HTTP/1.1 Host: www.webservicex.net Content-Type: text/xml; charset="utf-8" Content-Length: nnn SOAPAction= "http://www.webserviceX.NET/GetQuote" <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ?xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> ?<soap:Body> ???<GetQuote xmlns="http://www.webserviceX.NET/"> ?????<symbol>IBM</symbol> ???</GetQuote> ?</soap:Body> </soap:Envelope>

清單 3 返回的是按照 SOAP 協(xié)議封裝的調用響應,在 SOAP body 里面,GetQuoteResult 里面放置的是調用結果,返回的是 XML 表示的 IBM 在調用時刻的股價信息,

清單 3. A SOAP response 示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 HTTP/1.1 200 OK Content-Type: text/xml; charset='utf-8' Content-Length: nnn <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> ?<soap:Body> ???<GetQuoteResponse xmlns="http://www.webserviceX.NET/"> ?????<GetQuoteResult> <StockQuotes> <Stock> <Symbol> IBM </Symbol> <Last> 144.36 </Last> <Date> 11/18/2010 </Date> <Time> 4:00pm </Time> <Change> 0.00 </Change> <Open> N/A </Open> <High> N/A </High> <Low> N/A </Low> <Volume> 0 </Volume> <MktCap> 179.3B </MktCap> <PreviousClose> 144.36 </PreviousClose> <PercentageChange> 0.00% </PercentageChange> <AnnRange> 116.00 - 147.53 </AnnRange> <Earns> 11.001 </Earns> <P-E> 13.12 </P-E> <Name> International Bus </Name> </Stock> </StockQuotes> </GetQuoteResult> ???</GetQuoteResponse> ?</soap:Body> </soap:Envelope>

從清單 2 和清單 3 可以看出,基于 SOAP 的 Web 服務把 SOAP 請求和 SOAP 響應封裝在 soap Envelope 中,服務的調用端需要自己構建這個 SOAP 信封,并且需要一定的 code 去做解析工作。一般來說,XML 的解析是一項復雜度比較高的任務,比較耗時,這將會影響整個程序的性能。

下面我們來看一下以 REST 服務的方式怎么提供和清單 1 對應的股票查詢的能力。首先我們還是來看一下服務的描述,如清單 4 所示。

清單 4. 獲取股價的 REST 服務的描述
1 2 3 4 5 6 7 8 <?xml version="1.0" encoding="UTF-8"?> <service xmlns="http://www.ibm.com/rest/description/1.0/"> ?<title> Stock quote for a company Symbol </title> ?<template httpMethod="GET" url=" http://www.webservicex.net/stockquote.asmx/GetQuote?symbol={symbol}"/> ?<parameter name="symbol" required="true" ?defaultValue="IBM" style="template"/> </service>

和清單 1 比較,清單 4 顯得特別簡潔明了,語義也特別清楚。這給程序員的處理程序很大的簡化的可能性。清單 5 和清單 6 顯示了獲取股價的 REST 服務的調用。從清單 5 可以看出,請求的發(fā)送非常的簡單,僅僅是一個 HTTP url,而清單 6 顯示的查詢結果要清單 3 的查詢結果看起來語義要清楚很多。

清單 5. A REST Request over HTTP 示例
1 2 GET /stockquote.asmx/GetQuote?symbol=IBM?? HTTP/1.1 Host: www.webservicex.net
清單 6. A REST Response over HTTP 示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 HTTP/1.1 200 OK Date: Fri, 12 Sept 2010 17:15:33 GMT Last-Modified: Fri, 12 Sept 2010 17:15:33 GMT ETag: "2b3f6-a4-5b572640" Accept-Ranges: updated Content-Type: text/xml; charset="utf-8" <StockQuotes> <Stock> <Symbol> IBM </Symbol> <Last> 144.36 </Last> <Date> 11/18/2010 </Date> <Time> 4:00pm </Time> <Change> 0.00 </Change> <Open> N/A </Open> <High> N/A </High> <Low> N/A </Low> <Volume> 0 </Volume> <MktCap> 179.3B </MktCap> <PreviousClose> 144.36 </PreviousClose> <PercentageChange> 0.00% </PercentageChange> <AnnRange> 116.00 - 147.53 </AnnRange> <Earns> 11.001 </Earns> <P-E> 13.12 </P-E> <Name> International Bus </Name> </Stock> </StockQuotes>

分析 SOAP 的 Web 服務和 REST 服務的關系

現在你被認為已經清楚了基于 SOAP 的 Web 服務和 REST 服務的描述,以及已經會調用他們。接下來,我們來看一下這兩種服務的邏輯關系。

  • 面向方法和面向資源。從清單 1 可以看出,SOAP 服務是按照面向方法的方法論來設計的,需要服務提供者清楚的給出每個方法的名稱、輸入參數、輸出詳細描述、綁定等等,這些又再次封裝在消息 message 中。而從清單 4 中我們可以看出,REST 服務是面向資源的,服務提供者只需要告訴用于定位到服務的 URL template 以及要實例化這個 template 所有的參數描述。為了使這個服務可以工作,所以這里我們用了 http://www.webservicex.net/stockquote.asmx/GetQuote?symbol={symbol},但是更好的 URL 格式應該是 http://www.webservicex.net/stockquote.asmx/Quote?symbol={symbol},也許你已經發(fā)現了,兩個 URL 只是 GetQuote 和 Quote 的差別。奧妙就在這。GetQuote 看起來像一個方法名稱,而 Quote 是一個名詞,是一個資源。知道了這個差別,可以把 SOAP 服務的輸出作為一種資源,對應提供 REST 服務。
  • 參數對應。在 SOAP 描述文件中我們看到調用一個 SOAP Action 所需要的輸入的詳細描述。這些參數是系統(tǒng)提供服務所要求的必須的輸入。而在 REST 服務中,用戶看到的就是一個 URL,所以,我們可以把 SOAP Action 的輸入用 query string 的形式放到 REST 服務的 URL template 中。之所以叫 template,是因為不同的輸入會對應不同的 URL 示例,也就是說對應到不同的資源示例。
  • 知道了兩種服務間的邏輯關系,接下來,我們開始用程序把 SOAP 服務轉化成 REST 服務,當然,如果系統(tǒng)需要,你也可以把 REST 服務轉成 SOAP 服務。

    SOAP Web 服務和 REST 服務的轉換

    很多種方式,可以把 SOAP 服務轉化成 REST 服務。最直接的方式,程序員可以自己寫程序,實現一個 proxy,提供 REST 端點,然后通過 proxy 把 REST 請求轉發(fā)到 SOAP 端點,然后再實現調用結果的處理。這里我們主要介紹用 IBM 的一些產品來實現轉化的方法。IBM WebSphere sMash 和 IBM Mashuphub 都可以實現這種轉化。這里著重介紹用 IBM WebSphere sMash 平臺實現的方法。使用 IBM Mashuphub 的實現方式請參考 IBM Mashup Center 初探 : 第二部分。

    開始之前

  • 了解 WebSphere sMash
  • WebSphere sMash 即以前的 Project Zero, 它為快速簡便地開發(fā)交互式 Web 應用程序提供了開發(fā)環(huán)境。這個項目的目的是為 Web 開發(fā)提供一個完整的基礎設施,讓應用程序開發(fā)人員可以將注意力集中在業(yè)務邏輯上。花一些時間瀏覽和熟悉 ?Project Zero Web 站點。可以加入 Project Zero 社區(qū)、為這個項目做貢獻,或參與論壇,在各個開發(fā)階段對項目進行評價。本文只要求您的計算機上安裝了合適的 Java? Development Kit (JDK)。

  • 創(chuàng)建 WebSphere sMash 開發(fā)環(huán)境
  • 遵循下面的步驟,創(chuàng)建 WebSphere sMash 開發(fā)環(huán)境。

    Step 1:從 WebSphere sMash 網站下載工具包 zero.zip。

    Step 2: 解壓 zero.zip 到任意文件夾。如圖 1 所示。

    圖 1. 解壓 zero.zip 到任意文件夾

    Step3: 設置環(huán)境變量 ZERO_HOME 和 Path。如圖 2 所示。

    圖 2. 設置環(huán)境變量
    圖 2. 設置環(huán)境變量

    Step4: 在命令行運行 zero resolve 命令。如圖 3 所示。

    圖 3. 命令行運行 zero resolve 命令

    Step5: 創(chuàng)建 eclipse 開發(fā)環(huán)境,詳細步驟請參考 Plug-in for Java and Groovy。

    Step6: 創(chuàng)建一個 WebSphere sMash 新項目,取名 SOAP2REST。如圖 4 所示。

    圖 4. 創(chuàng)建 zero 項目 SOAP2REST

    開始轉換

    sMash 提供了一個組件叫 zero.connection.soap.REST2SOAPHandler,它封裝了 SOAP 協(xié)議,負責構建 SOAP header,發(fā)送 SOAP 請求,調用成功后,它返回 SOAP body。所以程序員只需要做其中很小的一部分工作就可以完成 SOAP 到 REST 的轉換。按照下面的步驟完成轉化的過程。

    Step 1: 在 zero.config 文件里面添加如清單 7 所示的代碼片段,配置轉換 hanlder 以及轉換的對應關系。

    清單 7. 在 zero.config 中申明 REST2SOAPHandler
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 /config/connection/destinations += { ?"http://localhost:9980/cms/*": { ?"handlers" : [ ?{ "class" : "zero.core.connection.handlers.logger.SimpleJavaLoggerHandler.class" }, ?{ "class" : "zero.connection.soap.REST2SOAPHandler", ?"config" : { ???"endpointAddress" : "http://www.webservicex.net/stockquote.asmx", ???"SOAPVersion" : "1.1", ???"r2sMapping" : [ ?????{ ??????"RESTOperation" : "POST", ??????"SOAPBodyTemplate" : "stockquoterequest.gt", ???????"URLMatch" : "/cms/stockquote/{symbol}", "SOAPAction": "http://www.webserviceX.NET/GetQuote" ????????} ????????????? ????????] ??????????} ????????}, { "class" : "zero.core.connection.handlers.logger.SimpleJavaLoggerHandler.class", ????"config" : { "request" : { "keys" : ["/connection/request/body", "/connection/request/soapHeaders"] }, "response" : { "keys" : ["/connection/response/body", ?"/connection/response/soapHeaders"] } ????????} ??????} ????] ??} ?}

    在清單 7 中,配置 REST2SOAPHandler 的各種參數,比如 endpointAddress,SOAPVersion,r2sMapping,實現類等。在 r2sMapping 中,配置 SOAP 和 REST 的對應關系,SOAP 操作由 SOAPAction 屬性指定,相對應的 REST 的操作屬性由 RESTOperation 指定;另外需要指定的是 SOAPBodyTemplate,用 gt 格式的文件指定;URLMatch 表明了 SOAP 服務端點和 REST 服務端點的對應。在清單 8 給出了 stockquoterequest.gt 的內容。

    清單 8. 指明 SOAP 請求 Header 中的內容
    1 2 3 4 5 6 <% // the SOAP request body %> <GetQuote xmlns="http://www.webserviceX.NET/"> ?????<symbol><%=r2s_getParam("symbol")%></symbol> </GetQuote>

    其中 r2s_getParam("symbol") 指的是從 REST 請求的 request 里面取出來參數的值。比如 REST 請求是 http://localhost:9980/stockquote.gt?symbol=IBM,那么 r2s_getParam("symbol") 的值就是 IBM.

    指明了 handler 和 SOAP 請求后,我們需要創(chuàng)建一個 public 的 zero resource,在 public 目錄下面,我們把這個 resource 叫做 stockquote.gt 吧,清單 9 給出了具體的內容。

    清單 9. 聲明一個 zero 的 public 的資源 stockquote.gt
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <% import zero.core.connection.*; def symbol = java.net.URLEncoder.encode(request.params.symbol[]) logger.INFO{symbol} %> <% try { // 這里的 URL 應該和 zero.config 中的 URL 對應,并指明 REST 的操作為 POST conn = new Connection("http://localhost:9980/cms/stockquote/${symbol}", ??Connection.Operation.POST); // 指明 content-type conn.addRequestHeader("Content-Type", "application/xml"); // 發(fā)送請求 resp = conn.getResponse(); body = resp.getResponseBodyAsString(); if (body == null) { throw new Exception("Response body incorrect: " + body.toString()); } // 取出服務返回的相應 def respObj = zero.json.Json.decode(body); request.json.output = respObj; // 指明一個 gt 用來處理返回的相應,如清單 10 request.view = "stockquote.gt"; render() } catch (Exception e) { e.printStackTrace(); print("<p><strong>Test failed!</strong></p><p> "+zero.util.XMLEncoder.escapeXML(e.toString())+"</p>"); } %>

    聲明了 public 的資源后,用戶就可以用 http://localhost:9980/stockquote.gt?symbol=IBM 的方式訪問資源了。

    清單 10. 處理返回的相應的 groovy 模板
    1 2 3 4 5 6 <% headers.out."Content-Type" = "application/xml" def respObj = request.json.output[] def stockquote = respObj.GetQuoteResponse.GetQuoteResult print(stockquote); %>

    結束語

    本文作為 REST 服務最佳實踐的第三篇,通過一個實際的例子,從兩種不同類型的 Web 服務的描述入手,輔助于兩種不同技術實現的 Web 服務的調用實例,詳細介紹 SOAP Web 服務和 REST 服務的關系,并示例介紹基于 WebSphere sMash 的 SOAP Web 服務和 REST 服務的轉換,從而使程序員可以輕松的利用已有系統(tǒng)的功能,快速構建 REST 服務。

    總結

    以上是生活随笔為你收集整理的把 SOAP 服务转化为 REST 服务(REST Service 的最佳实践,第 3 部分)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。