ruby on rails_使用Ruby on Rails和Action Web Service创建Web服务

ruby on rails

Rails是一个Web应用程序框架,其中包括使用Model-View-Control(MVC)模式创建数据库支持的Web应用程序所需的一切。 Action Web Service的最简洁定义是在其README文件中:“ Action Web Service提供了一种使用Rails发布可互操作的Web Service API的方法,而无需花费大量时间来研究协议细节。” 在本文中,您将学习如何安装Rails和Action Web Service模块并开始使用XML-RPC编程。

硬件和软件要求

连接到能够运行Ruby的网络的任何计算机都应具有足够的处理能力来处理此处提供的代码。 需要Ruby V1.86或更高版本,以及RubyGems和Rails。 我们讨论了如何在运行Microsoft®Windows®的计算机上安装它们。

Web服务如何工作

Web服务是一种软件系统,旨在通过网络进行互操作的交互。 Web服务是用WSDL文档定义的。 其他系统使用SOAP消息与Web服务进行交互,该消息通过HTTP和XML序列化进行传输。 Web服务是一种抽象资源,它提供由代理实现的一组功能,该功能发送和接收消息。 提供者实体通过提供者代理提供Web服务的功能。 请求者实体将Web服务功能与请求者代理一起使用。

Web服务实现了各种技术,包括XML,SOAP和WSDL。 XML是用于数据交换的标准格式。 Web服务请求和响应以XML消息的形式发送。 在XML文档中可以指定XML文档中可以指定的元素和属性。 SOAP提供了用于打包和交换XML消息的标准框架。 WSDL是可在http://schemas.xmlsoap.org/wsdl/上找到的XML文档,该文档定义了一个名称空间,用于将Web服务描述为对消息进行操作的一组端点。 WSDL文档指定Web服务提供的操作(方法)以及XML消息的格式。

创建一个Web服务

在详细讨论Ruby on Rails中的Web服务支持之前,我们将使用Action Web Service模块创建一个简单的Web服务。 首先,我们在Windows计算机上安装Ruby。 概述的步骤非常简单(请参阅参考资料 ,下载Ruby和Ruby on Rails,以及其他有关描述如何使用Ruby on Rails的developerWorks文章):

  1. 对于Windows用户,请下载最新版本的Ruby Windows安装程序(当前为Ruby V1.8.6-25),然后双击可执行文件。 将Ruby安装在C:/ ruby​​目录中。 还安装了用于安装其他gem的标准Ruby软件包管理器RubyGems。 接下来,安装Rails。 从C:/ ruby​​目录(安装Ruby的目录)中,运行以下命令来安装Rails和依赖项: c:/ruby>gem install rails --include-dependencies
  2. 使用Rails 2.0版本时,默认包中不包含Action Web Service gem。 使用以下命令安装actionwebservice gem: c:/ruby>gem install actionwebservice 。 在撰写本文时, actionwebservice V1.2.6是最新版本。 如果使用的是Rails的早期版本(Rails V2.0之前的版本),则actionwebservice gem将包含在默认软件包中。
  3. 通过输入C:/ruby>rails webservice为Web服务创建Rails应用程序。
  4. 在app目录中创建一个apis目录,然后创建一个Web服务API类HelloMessageApi ,该类扩展了ActionWebService::API::Base类。 将以下Ruby脚本存储到app / apis目录中的hello_message_api.rb中。
    清单1. Web服务API类HelloMessageApi
    class HelloMessageApi < ActionWebService::API::Base
      api_method :hello_message, :expects => [{:firstname=>:string}, 
    {:lastname=>:string}], :returns => [:string]
    
    
    end
  5. 创建一个控制器脚本,该脚本定义一个控制器类: HelloMessageController 。 将以下Ruby代码复制到控制器脚本中,并将控制器脚本hello_message_controller.rb保存在app/controllers目录中。
    清单2.控制器类HelloMessageController
    class HelloMessageController < ApplicationController
     
    web_service_api HelloMessageApi
     web_service_dispatching_mode :direct
      wsdl_service_name 'hello_message'
      web_service_scaffold :invoke
    
      def hello_message(firstname, lastname)
        return "Hello "+ firstname +" "+lastname
      end
    end
  6. 通过输入C:/ruby/webservice>ruby script/server启动WEBrick Web C:/ruby/webservice>ruby script/server
  7. 显示具有URL http://localhost:3000/hello_message/wsdl的Web服务的WSDL文件。
    图1. Web服务WSDL
    Web服务WSDL
  8. 使用http://localhost:3000/hello_message/invoke Web服务。 将显示该Web服务的API方法。 选择HelloMessage方法。
    图2.调用Web服务
    调用Web服务
  9. 要测试Web服务,请指定一个名字和一个姓氏,然后单击Invoke
    图3.调用Web服务方法
    调用Web服务方法
  10. 返回值以及请求XML和响应XML被输出。
图4. Web服务的输出
Web服务的输出

让我们详细讨论Web服务。 Web服务API类定义了Web服务提供的方法。 示例API类定义了hello_message方法,该方法采用两个string类型的参数并返回一个字符串值。 使用ActionWebService::API::Base类的api_method方法定义API方法。 Web服务的WSDL是从API类创建的。 Web服务API类扩展了ActionWebService::API::Base类。 控制器类包含Web服务可用于客户端的代码。 web_service_api选项指定API定义类。 web_service_dispatching_mode选项指定了调度方法,远程调用者将在其中发送其调用方法,端点URL,以及如何将方法调用路由到实现该方法的对象。

在直接分派模式下,方法调用直接对控制器进行。 API方法的实现在控制器类中定义为公共实例方法。 直接模式是默认模式。 wsdl_service_name选项指定Web服务名称。 web_service_scaffold选项生成用于方法调用的Web服务支架。 Web服务支架类似于Active Record的支架。 在示例Web服务中指定的invoke方法列出了连接到控制器的所有API中的所有方法。 客户端类可使用控制器类中的hello_message操作来进行方法调用。

Web服务API类

在前面的示例中,Web服务API类是HelloMessageApi 。 Web服务API类扩展了ActionWebService::API::Base类,并指定了可用于Web服务中的API的方法。 该类的一些方法将在下面讨论。

表1. ActionWebService :: API :: Base方法
方法 描述
api_method(名称,选项= {}) 指定API方法; 选项是:expects-Signature用于方法输入参数,:returns-Signature用于返回值,:expects_and_returns-Signature用于输入参数和返回值
api_method_name(public_name) 为公共方法名称指定服务方法名称
api_methods() 在此API上指定服务方法的哈希
has_public_api_method?(public_name) 指定公共方法在此API上是否具有相应的服务方法
soap_client(endpoint_uri,options = {}) 指定一个SOAP客户端
xmlrpc_client(endpoint_uri,options = {}) 指定一个XML RPC客户端

定义API类的过程如下:

  1. 确定要在API上提供哪些方法。
  2. 创建一个扩展ActionWebService::API::Base类的类。
  3. 使用api_method选项定义方法,包括方法签名。

派遣

调度是Web服务上方法调用的分布。 调度方法是指远程调用者将调用消息发送到何处,以及方法调用如何路由到方法实现对象。 基于调度方法实现API。 可以使用三种调度方法:

  1. 直接
  2. 委托
  3. 分层的

直接派遣

使用直接分派方法,API定义类将附加到控制器类,并且API方法在控制器类中作为公共实例方法实现。 正如前面讨论的示例应用程序中一样,直接调度被指定为web_service_dispatching_mode :direct

直接调度方法是默认方法。 使用直接分派方法,控制器类可以仅实现一个API。 具有直接分派的Web服务的端点URL为http://SERVER/CONTROLLER_NAME/api格式。

前面讨论的示例Web服务的端点URL是http://localhost:3000/hello_message/api ,如WSDL文档的service元素中所指定。

清单3.端点URL
<service name="hello_messageService">
 <port name="hello_messageHelloMessagePort" 
  binding="typens:hello_messageHelloMessageBinding">
  <soap:address location=
   "http://localhost:3000/hello_message/api" />
  </port>
  </service>

在直接分派模式下,如果API定义类与控制器类同名并且存储在app/apis目录中的apiclass_api.rb格式的Ruby文件中,则可以省略web_service_api选项。 在前面讨论的示例应用程序中,在控制器类中不需要web_service_api选项,因为API类存储在hello_message_api.rb 。 使用直接分派方法开发Action Web Service Web服务的过程如下:

  1. 定义一个API类,一个扩展ActionWebService::Base类的类,并定义API方法。
  2. 使用web_service_api选项将API Web服务类附加到控制器类。
  3. 使用web_service_dispatching_mode :direct将调度模式设置为“ direct”。
  4. 在控制器类中将API方法实现为公共实例方法。
  5. 通过将脚手架添加到控制器类来测试Web服务。

委托派遣

direct调度方法的局限性在于,控制器类只能实现一个API。 在委派调度方法中,控制器类可以实现多个API。 我们将以一个示例讨论delegated调度。

定义两个API类: HelloMessageApiDeveloperApi 。 将HelloMessageApi类存储在app/apis目录中的hello_message_api.rb Ruby脚本中。 HelloMessageApi类定义了hello_message API方法,该方法采用两个字符串参数(名字和姓氏)并返回一个字符串值。 hello_message_api.rb脚本如下所示。

清单4. hello_message_api.rb
class HelloMessageApi < ActionWebService::API::Base
  api_method :hello_message, :expects => 
  [{:firstname=>:string}, 
  {:lastname=>:string}], :returns => [:string]

end

DeveloperApi类存储在app / apis目录中的developer_api.rb Ruby脚本中。 DeveloperApi类定义一个developer方法,该方法接受两个字符串参数并返回一个字符串值。 下面显示了developer_api.rb脚本。

清单5. developer_api.rb
class DeveloperApi < ActionWebService::API::Base
  api_method :developer, :expects => 
  [{:firstname=>:string}, 
{:lastname=>:string}], :returns => [:string]

end

为每个API类创建一个服务类。 服务类扩展了ActionWebService::Base类。 服务类实现API类中定义的方法。 使用web_service_api选项,API类与服务类一起附加。 HelloMessageService类实现HelloMessageApi API类。 将HelloMessageService服务类作为Ruby脚本hello_message_service.rb存储在app/models目录中。 hello_message_service.rb脚本如下所示。

清单6. hello_message_service.rb
class HelloMessageService < ActionWebService::Base
 web_service_api HelloMessageApi

def hello_message(firstname, lastname)
    return "Hello "+ firstname +" "+lastname
  end
end

同样,为DeveloperApi API类创建一个服务类DeveloperServiceDeveloperService类的Ruby脚本作为developer_service.rb存储在app/models目录中。 下面显示了developer_service.rb脚本。

清单7. developer_service.rb
class DeveloperService < ActionWebService::Base
 web_service_api DeveloperApi

def developer(firstname, lastname)
    return "This Web service is developed by "+ firstname +" 
    "+lastname
  end
end

为服务类创建一个控制器类。 使用以下选项设置将调度模式设置为“ delegated”: web_service_dispatching_mode :delegated 。 使用web_service选项将服务类附加到控制器类。 例如, HelloMessageService类通过以下声明附加到控制器类: web_service :hello_message, HelloMessageService.new

Hello_message是表示HelloMessageService类的Web服务。 要测试Web服务,请使用web_service_scaffold选项将脚手架添加到控制器类。 web_service_scaffold :invoke 。 将控制器类存储在app/controllers目录中。 控制器脚本delegated_controller.rb如下所示。

清单8. proxyed_controller.rb
class DelegatedController < ApplicationController
 web_service_dispatching_mode :delegated

 web_service :hello_message, HelloMessageService.new
 web_service :developer, DeveloperService.new
 web_service_scaffold :invoke
end

控制器类不必命名为DelegatedController 。 接下来,我们将测试Web服务。 如果尚未启动WEBrick Web服务器,请启动它: C:/ruby/helloservice>ruby script/server 。 使用URL http://localhost:3000/delegated/invoke方法的Web服务列表。 将列出控制器类中指定的所有API服务类的API方法。

图5.调用委托的Web服务
调用委托的Web服务

与直接调度方法相比,可以使用服务类将一个以上的API类附加到控制器类。 使用委托方法开发Action Web Service Web服务的过程如下:

  1. 定义要由Web服务实现的API类。
  2. 为每个API类创建一个服务类,该类扩展了ActionWebService::Base类。 使用web_service_api选项将API类附加到服务类。
  3. 将服务类中的API方法实现为公共实例方法。
  4. 创建一个控制器类,并将调度模式设置为“委托”。
  5. 使用web_service option将服务类附加到控制器类。
  6. 通过使用web_service_scaffold选项为Web服务生成支架来测试Web服务。

分层调度

分层调度方法过程与委托调度方法类似,不同之处在于以下声明: web_service_dispatching_mode :layered 。 每个方法调用均以servicename.methodname格式的服务名称作为前缀。 还可以使用由web_service_scaffold选项生成的支架来测试分层的分派方法Web服务。

协议客户端

动作Web服务提供了一些用于访问远程Web服务的客户端类。 可以使用web_client_api帮助函数从控制器内部访问远程Web服务,也可以直接使用ActionWebService::Client::SoapActionWebService::Client::XmlRpc类的实例来访问远程Web服务。 在本节中,我们将创建一个Action Web Service Web服务,并使用web_client_api函数和直接实例方法调用来访问该Web服务。 我们需要创建两个单独的Rails应用程序-一个用于Web服务,另一个用于客户端。 通过输入C:/ruby>rails helloservice为Web服务创建Rails应用程序。

使用web_service脚本生成器使用HelloApi API类和getMsg API方法创建Hello Web服务:

C:/ruby/helloservice>ruby script/generate web_service Hello getMsg

在apis目录中以Ruby脚本hello_api.rb创建一个HelloApi API类。 在controllers目录中创建了hello_controller.rb控制器脚本。 HelloController控制器类包括getMsg控制器动作。 控制器类还指定wsdl_service_name (Web服务名称)。 运行Web服务时,Web服务的WSDL可用。 修改控制器脚本以指定web_service_api选项,并指定与脚手架web_service_scaffold选项。 web_service_api选项将控制器映射到API类。 修改getMsg控制器操作以采用字符串参数并返回字符串值。 该getMsg方法实现getMsg方法在API类。 修改后的控制器脚本如下所示。

清单9. hello_controller.rb
class HelloController < ApplicationController
  wsdl_service_name 'Hello'

web_service_api HelloApi
web_service_scaffold :invoke


  def getMsg(name)
"Hello "+ name
 end
end

修改HelloApi API类,以向getMsg方法签名添加参数和返回值。 HelloApi类如下所示。

清单10. HelloApi
class HelloApi < ActionWebService::API::Base
  api_method :getMsg, :expects => [:name=>:string], 
:returns => [:string]
end

接下来,我们将测试Web服务。 从Web服务目录中使用以下命令启动Web服务: C:/ruby>webservice>ruby script/server 。 使用URL http://localhost:3000/hello/invoke Web服务。 列出了用于Web服务的API方法。 单击GetMsg方法。

图6.调用Web服务框架
调用Web服务支架

显示名称输入字段。 您还可以选择协议:SOAP或XML RPC。 在“名称”字段中指定一个值,然后单击“ 调用”

图7.调用Web服务方法
调用Web服务方法

使用名称参数值“ Steve”调用getMsg Web服务方法,并返回输出值。 同样,显示请求XML和响应XML消息。

图8. Web服务的返回值
从Web服务返回值

接下来,我们使用C:/ruby>rails helloadmin为客户端创建一个Rails应用程序。 在helloadmin Rails应用程序的app目录中创建一个apis目录,并将hello_api.rb脚本从helloservice Rails应用程序复制到apis目录。 为Web服务客户端创建控制器脚本:

C:/ruby/helloadmin>ruby script/generate controller helloadmin getMsg

创建一个由getMsg控制器动作组成的HelloadminController控制器类。 使用web_client_api函数从控制器类访问Web服务API:

web_client_api :hello, :xmlrpc, "http://localhost:3001/hello/api"

web_client_api(name, protocol, endpoint_uri, options={})方法使用指定的协议创建一个使用name参数指定的受保护方法,以与指定的端点URI进行通信。 我们使用xmlrpc协议创建了一个hello方法,以与端点URI http://localhost:3001/hello/api 。 我们在端口3001上运行Hello Web服务,并通过端口3000上的客户端访问Web服务。修改getMsg控制器操作,以为Web服务方法调用的输出创建变量。 使用通过web_client_api创建的hello方法,使用name参数作为该方法的输入来调用Hello Web服务的getMsg方法。 我们在index.rhtml视图模板中定义name参数值。 控制器脚本helloadmin_controller.rb如下所示。

清单11. helloadmin_controller.rb
class HelloadminController < ApplicationController

web_client_api :hello, :xmlrpc, "http://localhost:3001/hello/api"

    def getMsg

       @service_output= hello.getMsg(params[:name])
        
    end

end

您还可以使用ActionWebService::Client::SoapActionWebService::Client::XmlRpc类的实例直接访问Hello Web服务。 还可使用ActionWebService::Client::Soap类的实例表示helloadmin_controller.rb脚本,如下所示。

清单12. helloadmin_controller.rb
class HelloadminController < ApplicationController

    def getMsg

hello_client = ActionWebService::Client::Soap.new(HelloApi, 
"http://localhost:3001/hello/api")

       @service_output= hello_client.getMsg(params[:name])
        
    end

end

views/helloadmin目录中创建index.rhtml视图模板,并在RHTML模板中添加带有输入字段“ name”的表单。 提交表单后,将调用Helloadmin控制器的getMsg方法。 视图模板index.rhtml如下所示。

清单13. index.rhtml
<html>
   <head>
      <title>Hello Web Service</title>
   </head>
   <body>
      <h1>Hello Web Service</h1>
      <p>
      This Rails application tests a Web service.
      </p>
      <%= start_form_tag :action=> 'getMsg' %>
      <p><label>Name</label><br/>
      <%= text_field 'name', '' %></p>
      <%= submit_tag "Get Message" %>
      <%= end_form_tag %>
   </body>
</html>

修改getMsg.rhtml视图模板,以输出变量@service_output的值,该值在Helloadmin控制器类的getMsg方法中定义。 getMsg.rhtml视图模板如下所示。

清单14. getMsg.rhtml
<html>
   <head>
      <title>Hello Web Service</title>
   </head>
   <body>
      <h1>Hello Web Service </h1>
      <p>
      
      </p>
      <p>
      <%= @service_output %>
      </p>
   </body>
</html>

接下来,我们将使用客户端Rails应用程序测试Web服务Hello 。 从helloservice目录中使用以下命令在端口3001上启动Web服务:

C:/ruby/helloservice>ruby script/server --port=3001

helloadmin目录中的默认端口3000上启动客户端Rails应用程序:

C:/ruby/helloadmin>ruby script/server

该示例应用程序演示了如何从协议客户端访问Web服务。 使用URL http://localhost:3000/helloadmin/index调用Helloadmin控制器的索引控制器操作。 显示index.rhtml视图模板。 指定一个名称值,然后单击“ 获取消息”

图9.使用协议客户端测试Web服务
使用协议客户端测试Web服务

Helloadmin控制器的getMsg方法被调用。 使用使用web_client_api选项定义的hello方法,可以访问Hello Web服务,并调用该Web服务的getMsg方法。 Web服务的输出显示在getMsg.rhtml视图模板中。

图10. Web服务的输出
Web服务的输出

使用协议客户端访问Web服务的过程如下:

  1. 为Web服务创建Rails应用程序。
  2. 创建一个Web服务。
  3. 定义一个或多个API方法并在控制器类中实现该方法。
  4. 为协议客户端创建Rails应用程序。
  5. 定义API类和API方法。
  6. 使用web_client_api选项( ActionWebService::Client::SoapActionWebService::Client::XmlRpc web_client_api的实例)从客户端应用程序控制器访问Web服务。
  7. 在客户端控制器类中实现API方法。
  8. 在端口3001上启动Web服务。
  9. 在端口3000上启动客户端应用程序。
  10. 从RHTML视图模板调用API方法,并将Web服务输出输出到另一个RHTML视图模板。

结论

尽管Rails V2.x在默认捆绑包中包含了基于REST的ActiveResource gem,而不是在基于SOAP的Action Web Service gem中,但基于SOAP的Web service也有其优势(请参阅参考资料 )。 在本文中,我们讨论了如何使用Action Web Service gem创建基于SOAP和基于XML-RPC的Web服务,并提供了一些示例来帮助您开始使用该技术。


翻译自: https://www.ibm.com/developerworks/opensource/library/os-ws-rubyrails/index.html

ruby on rails

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值