# Ruby Web Services 應用 - SOAP4R
## 什么是 SOAP?
簡單對象訪問協議(SOAP,全寫為Simple Object Access Protocol)是交換數據的一種協議規范。
SOAP 是一種簡單的基于 XML 的協議,它使應用程序通過 HTTP 來交換信息。
簡單對象訪問協議是交換數據的一種協議規范,是一種輕量的、簡單的、基于XML(標準通用標記語言下的一個子集)的協議,它被設計成在WEB上交換結構化的和固化的信息。
更多 SOAP 教程請查看:[http://www.w3cschool.cc/soap/soap-tutorial.html](/soap/soap-tutorial.html)。
## SOAP4R 安裝
SOAP4R 由Hiroshi Nakamura開發實現,用于 Ruby 的 SOAP 應用。
SOAP4R 下載地址:[http://raa.ruby-lang.org/project/soap4r/](//raa.ruby-lang.org/project/soap4r/)。
**注意:**你的ruby環境可能已經安裝了該該組件。
Linux 環境下你也可以使用 gem 來安裝該組件,命令如下:
```
$ gem install soap4r --include-dependencies
```
如果你是window環境下開發,你需要下載zip壓縮文件,并通過執行 install.rb 來安裝。
## SOAP4R 服務
SOAP4R 支持兩種不同的服務類型:
* 基于 CGI/FastCGI 服務 (SOAP::RPC::CGIStub)
* 獨立服務 (SOAP::RPC:StandaloneServer)
本教程將為大家介紹如何建立獨立的 SOAP 服務。步驟如下:
### 第1步 - 繼承SOAP::RPC::StandaloneServer
為了實現自己的獨立的服務器,你需要編寫一個新的類,該類為 SOAP::RPC::StandaloneServer 的子類:
```
class MyServer < SOAP::RPC::StandaloneServer
...............
end
```
**注意:**如果你要編寫一個基于FastCGI的服務器,那么你需要繼承 SOAP::RPC::CGIStub 類,程序的其余部分將保持不變。
### 第二步 - 定義處理方法
接下來我們定義Web Services的方法,如下我們定義兩個方法,一個是兩個數相加,一個是兩個數相除:
```
class MyServer < SOAP::RPC::StandaloneServer
...............
# 處理方法
def add(a, b)
return a + b
end
def div(a, b)
return a / b
end
end
```
### 第三步 - 公布處理方法
接下來添加我們在服務器上定義的方法,initialize方法是公開的,用于外部的連接:
```
class MyServer < SOAP::RPC::StandaloneServer
def initialize(*args)
add_method(receiver, methodName, *paramArg)
end
end
```
以下是各參數的說明:
| 參數 | 描述 |
| --- | --- |
| **receiver** | 包含方法名的方法的對象。 如果你在同一個類中定義服務方法,該參數為 _self_。 |
| **methodName** | 調用 RPC 請求的方法名。 |
| **paramArg** | 參數名和參數模式 |
為了理解 _inout_ 和 _out_ 參數,考慮以下服務方法,需要輸入兩個參數:inParam 和 inoutParam,函數執行完成后返回三個值:retVal、inoutParam 、outParam:
```
def aMeth(inParam, inoutParam)
retVal = inParam + inoutParam
outParam = inParam . inoutParam
inoutParam = inParam * inoutParam
return retVal, inoutParam, outParam
end
```
公開的調用方法如下:
```
add_method(self, 'aMeth', [
%w(in inParam),
%w(inout inoutParam),
%w(out outParam),
%w(retval return)
])
```
### 第四步 - 開啟服務
最后我們通過實例化派生類,并調用 start 方法來啟動服務:
```
myServer = MyServer.new('ServerName',
'urn:ruby:ServiceName', hostname, port)
myServer.start
```
以下是請求參數的說明:
| 參數 | 描述 |
| --- | --- |
| **ServerName** | 服務名,你可以取你喜歡的 |
| **urn:ruby:ServiceName** | Here _urn:ruby_ 是固定的,但是你可以為你的服務取一個唯一的 _ServiceName_ |
| **hostname** | 指定主機名 |
| **port** | web 服務端口 |
### 實例
接下來我們通過以上的步驟,創建一個獨立的服務:
```
require "soap/rpc/standaloneserver"
begin
class MyServer < SOAP::RPC::StandaloneServer
# Expose our services
def initialize(*args)
add_method(self, 'add', 'a', 'b')
add_method(self, 'div', 'a', 'b')
end
# Handler methods
def add(a, b)
return a + b
end
def div(a, b)
return a / b
end
end
server = MyServer.new("MyServer",
'urn:ruby:calculation', 'localhost', 8080)
trap('INT){
server.shutdown
}
server.start
rescue => err
puts err.message
end
```
執行以上程序后,就啟動了一個監聽 8080 端口的本地服務,并公開兩個方法:add 和 div。
你可以再后臺執行以上服務:
```
$ ruby MyServer.rb&
```
## SOAP4R 客戶端
ruby 中使用 SOAP::RPC::Driver 類開發 SOAP 客戶端。接下來我們來詳細看下 SOAP::RPC::Driver 類的使用。
調用 SOAP 服務需要以下信息:
* SOAP 服務 URL 地址 (SOAP Endpoint URL)
* 服務方法的命名空間(Method Namespace URI)
* 服務方法名及參數信息
接下來我們就一步步來創建 SOAP 客戶端來調用以上的 SOAP 方法:add 、 div:
### 第一步 - 創建 SOAP Driver 實例
我們可以通過實例化 SOAP::RPC::Driver 類來調用它的新方法,如下所示:
```
SOAP::RPC::Driver.new(endPoint, nameSpace, soapAction)
```
以下是參數的描述:
| 參數 | 描述 |
| --- | --- |
| **endPoint** | 連接 SOAP 服務的 URL 地址 |
| **nameSpace** | 命名空間用于 SOAP::RPC::Driver 對象的所有 RPC . |
| **soapAction** | 用于 HTTP 頭部的 SOAPAction 字段值。如果是字符串是"" 則默認為 _nil_ |
### 第二步 - 添加服務方法
為 SOAP::RPC::Driver 添加 SOAP 服務方法,我們可以通過實例 SOAP::RPC::Driver 來調用以下方法:
```
driver.add_method(name, *paramArg)
```
以下是參數的說明:
| 參數 | 描述 |
| --- | --- |
| **name** | 遠程web服務的方法名 |
| **paramArg** | 指定遠程程序的參數 |
### 第三步 - 調用SOAP服務
最后我們可以使用 SOAP::RPC::Driver 實例來調用 SOAP 服務:
```
result = driver.serviceMethod(paramArg...)
```
serviceMethod SOAP服務的實際方法名,paramArg為方法的參數列表。
### 實例
基于以上的步驟,我們可以編寫以下的 SOAP 客戶端:
```
#!/usr/bin/ruby -w
require 'soap/rpc/driver'
NAMESPACE = 'urn:ruby:calculation'
URL = 'http://localhost:8080/'
begin
driver = SOAP::RPC::Driver.new(URL, NAMESPACE)
# Add remote sevice methods
driver.add_method('add', 'a', 'b')
# Call remote service methods
puts driver.add(20, 30)
rescue => err
puts err.message
end
```
以上我們只是簡單介紹 Ruby 的 Web Services 。 如果你想了解更多可以查看官方文檔:[Ruby 的 Web Services](//www.ruby-doc.org/stdlib/libdoc/soap/rdoc/index.html "Web Services with Ruby")
- Ruby 基礎
- Ruby 簡介
- Ruby 環境
- Ruby 安裝 - Unix
- Ruby 安裝 - Windows
- Ruby 命令行選項
- Ruby 環境變量
- Ruby 語法
- Ruby 數據類型
- Ruby 類和對象
- Ruby 類案例
- Ruby 變量
- Ruby 運算符
- Ruby 注釋
- Ruby 判斷
- Ruby 循環
- Ruby 方法
- Ruby 塊
- Ruby 模塊(Module)
- Ruby 字符串(String)
- Ruby 數組(Array)
- Ruby 哈希(Hash)
- Ruby 日期 & 時間(Date & Time)
- Ruby 范圍(Range)
- Ruby 迭代器
- Ruby 文件的輸入與輸出
- Ruby File 類和方法
- Ruby Dir 類和方法
- Ruby 異常
- Ruby 高級
- Ruby 面向對象
- Ruby 正則表達式
- Ruby 數據庫訪問 - DBI 教程
- Ruby CGI 編程
- Ruby CGI方法
- Ruby CGI Cookies
- Ruby CGI Sessions
- Ruby 發送郵件 - SMATP
- Ruby Socket 編程
- Ruby XML, XSLT 和 XPath 教程
- Ruby Web Services 應用 - SOAP4R
- Ruby 多線程
- 免責聲明