Logo    
Деловая газета CitCity.ru CITKIT.ru - все об Open Source Форумы Все публикации Учебный центр Курилка
CitForum    CITForum на CD    Подписка на новости портала Море(!) аналитической информации! :: CITFORUM.RU
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

24.04.2017

Google
WWW CITForum.ru
С Новым годом!
2008 г.

Веб-сервисы и Ruby

Александр Симаков, alexander-simakov.blogspot.com

Введение

Веб-сервисы - это технология, позволяющая приложениям, написанным на разных языках программирования и работающих на различных программно-аппаратных платформах легко обмениваться данными через четко-определенные интерфейсы. По своей сути, веб-сервисы являются одним из воплощений технологии RPC - удаленного вызова процедур. В основе веб-сервисов лежат следующие стандарты:

  • XML - для передачи структурированных данных;
  • SOAP - протокол обмена сообщениями на базе XML;
  • WSDL - язык описания интерфейсов веб-сервисов;
  • UDDI - каталог веб-сервисов.
В этой статье рассказывается о том как подключаться к веб-сервисам с использованием языка программирования Ruby. В качестве примера мы рассмотрим веб-сервис ЦБРФ для получения курса валют.

Установка

Для работы с веб-сервисами потребуется библиотека SOAP4R. Не смотря на то, что облегченная версия этой библиотеки уже включена в стандартную поставку Ruby, настоятельно рекомендуется установить полную версию. Если вы подключены к интернету напрямую, то достаточно всего одной команды:

# gem install soap4r

Bulk updating Gem source index for: http://gems.rubyforge.org
Install required dependency httpclient? [Yn] Y
Successfully installed soap4r-1.5.8
Successfully installed httpclient-2.1.2
Installing ri documentation for httpclient-2.1.2...
Installing RDoc documentation for httpclient-2.1.2...
Если вы подключены через прокси, то перед инсталляцией потребуется задать переменную окружения http_proxy. В Линуксе это можно сделать следующим образом:
export http_proxy=http://user:password@host:port
Для установки переменной окружения под Windows выберите "Мой компьютер" -> "Свойства" -> "Дополнительно" -> "Переменные среды"-> "Создать".

Если при работе через прокси-сервер вы столкнетесь с ошибкой "407 Proxy Authentication Required", прочитайте этот пост. Там описывается решение проблемы.

Подключение к веб-сервису

Описание веб-сервиса, к которому мы собираемся подключаться, расположено по адресу http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL. Описание задается на языке WSDL - Web Service Description Language. Фактически, это XML-документ определенной структуры.

В описании указывается какие методы предоставляет веб-сервис и как их следует вызывать. Нас интересует метод getCursOnDateXML. Он принимает в качестве аргумента дату и возвращает массив записей следующего вида:

  • Название валюты (Vname);
  • Номинал (Vnom);
  • Курс (Vcurs);
  • Цифровой код валюты (Vcode);
  • Символьный код валюты (VchCode).
Для того чтобы воспользоваться веб-сервисом нам необходимо сгенерировать клиентские заглушки (stubs). Эта процедура выполняется при помощи программы wsdl2ruby.rb, которая входит в состав библиотеки SOAP4R:
wsdl2ruby.rb --wsdl http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL --type client

ignored element: {http://schemas.xmlsoap.org/wsdl/soap12/}binding
ignored element: {http://schemas.xmlsoap.org/wsdl/soap12/}operation
ignored element: {http://schemas.xmlsoap.org/wsdl/soap12/}body
ignored element: {http://schemas.xmlsoap.org/wsdl/soap12/}address
I, [2008-09-07T00:04:04.847391 #5995]  INFO -- app: Creating class definition.
I, [2008-09-07T00:04:04.847750 #5995]  INFO -- app: Creates file 'default.rb'.
I, [2008-09-07T00:04:05.060365 #5995]  INFO -- app: Creating mapping registry definition.
I, [2008-09-07T00:04:05.060776 #5995]  INFO -- app: Creates file 'defaultMappingRegistry.rb'.
I, [2008-09-07T00:04:05.119316 #5995]  INFO -- app: Creating driver.
I, [2008-09-07T00:04:05.119752 #5995]  INFO -- app: Creates file 'defaultDriver.rb'.
I, [2008-09-07T00:04:05.219052 #5995]  INFO -- app: Creating client skelton.
I, [2008-09-07T00:04:05.219560 #5995]  INFO -- app: Creates file 'DailyInfoClient.rb'.
I, [2008-09-07T00:04:05.319125 #5995]  INFO -- app: End of app. (status: 0)
Как видно из отладочного вывода, программа сгенерировала четыре файла:
  • default.rb;
  • defaultMappingRegistry.rb;
  • defaultDriver.rb;
  • DailyInfoClient.rb.
Для работы с веб-сервисом необходимы первые три. Последний файл не обязателен. Это пример клиентского кода. Итак, теперь все готово для написания тестового приложения:
#!/usr/bin/ruby

#
# get_curs.rb
#
# Александр Симаков, <xdr (тчк) box на Google Mail>
# http://alexander-simakov.blogspot.com/
#

# Подключаем библиотеку SOAP4R
require 'rubygems'
require_gem 'soap4r'

# Подключаем клиентские заглушки
require 'defaultDriver.rb'

# При помощи этого объекта мы будем вызывать
# методы веб-сервиса
serv = DailyInfoSoap.new

# Выводить отладочную информацию если ruby
# был запущен с ключом -d
serv.wiredump_dev = STDERR if $DEBUG

# Формируем запрос
request = GetCursOnDateXML.new(DateTime.now)

# Отправляем запрос на сервер и получаем ответ
response = serv.getCursOnDateXML(request)

# Анализируем ответ и выводим результат
items = response.getCursOnDateXMLResult.valuteData.valuteCursOnDate

items.each do |item|
  puts "---------------------------------"
  puts "Название: " + item['Vname'].strip
  puts "Числовой код: " + item['Vcode']
  puts "Символьный код: " + item['VchCode']
  puts "Номинал: " + item['Vnom']
  puts "Курс: " + item['Vcurs']
end
Сохраните этот файл в той же директории и запустите его на выполнение. Вот как выглядел результат на момент написания статьи:
---------------------------------
Название: Австралийский доллар
Числовой код: 36
Символьный код: AUD
Номинал: 1
Курс: 21.0261
---------------------------------
Название: Фунт стерлингов Соединенного королевства
Числовой код: 826
Символьный код: GBP
Номинал: 1
Курс: 44.9826
---------------------------------
Название: Белорусский рубль
Числовой код: 974
Символьный код: BYR
Номинал: 1000
Курс: 11.9615
---------------------------------
Название: Датская крона
Числовой код: 208
Символьный код: DKK
Номинал: 10
Курс: 48.5829
---------------------------------
Название: Доллар США
Числовой код: 840
Символьный код: USD
Номинал: 1
Курс: 25.2626
---------------------------------
Название: Евро
Числовой код: 978
Символьный код: EUR
Номинал: 1
Курс: 36.2670
---------------------------------
Название: Исландская крона
Числовой код: 352
Символьный код: ISK
Номинал: 100
Курс: 28.8435
---------------------------------
Название: Казахский тенге
Числовой код: 398
Символьный код: KZT
Номинал: 100
Курс: 21.1120
---------------------------------
Название: Канадский доллар
Числовой код: 124
Символьный код: CAD
Номинал: 1
Курс: 23.8642
---------------------------------
Название: Китайский юань Жэньминьби
Числовой код: 156
Символьный код: CNY
Номинал: 10
Курс: 36.9304
---------------------------------
Название: Норвежская крона
Числовой код: 578
Символьный код: NOK
Номинал: 10
Курс: 45.2719
---------------------------------
Название: СДР (специальные права заимствования)
Числовой код: 960
Символьный код: XDR
Номинал: 1
Курс: 39.0691
---------------------------------
Название: Сингапурский доллар
Числовой код: 702
Символьный код: SGD
Номинал: 1
Курс: 17.7668
---------------------------------
Название: Новая турецкая лира
Числовой код: 949
Символьный код: TRY
Номинал: 1
Курс: 20.7564
---------------------------------
Название: Украинская гривна
Числовой код: 980
Символьный код: UAH
Номинал: 10
Курс: 53.5225
---------------------------------
Название: Шведская крона
Числовой код: 752
Символьный код: SEK
Номинал: 10
Курс: 38.3377
---------------------------------
Название: Швейцарский франк
Числовой код: 756
Символьный код: CHF
Номинал: 1
Курс: 22.5962
---------------------------------
Название: Японская иена
Числовой код: 392
Символьный код: JPY
Номинал: 100
Курс: 23.2653
Отмечу, что данные возвращаются в кодировке UTF-8. Таким образом, если на вашем компьютере используется другая кодировка, то названия валют будут нечитаемыми. В этом случае придется конвертировать данные вручную.

Как это работает

Итак, давайте разберемся как работает эта программа. Нам известно, что метод getCursOnDateXML получает на вход дату и возвращает информацию о курсе валют. Но каким образом передать методу аргумент и как интерпретировать полученный ответ? Для начала, откроем файл defaultDriver.rb и найдем в нем название интересующего нас метода:

require 'default.rb'
require 'defaultMappingRegistry.rb'
require 'soap/rpc/driver'

class DailyInfoSoap < ::SOAP::RPC::Driver
  DefaultEndpointUrl = "http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx"

  Methods = [
    ...
    [ "http://web.cbr.ru/GetCursOnDateXML",
      "getCursOnDateXML",
      [ ["in", "parameters", ["::SOAP::SOAPElement", "http://web.cbr.ru/", "GetCursOnDateXML"]],
        ["out", "parameters", ["::SOAP::SOAPElement", "http://web.cbr.ru/", "GetCursOnDateXMLResponse"]] ],
      { :request_style =>  :document, :request_use =>  :literal,
        :response_style => :document, :response_use => :literal,
        :faults => {} }
    ],
    ...
  end
end
Видно, что на вход поступает объект класса GetCursOnDateXML, а на выходе мы получаем объект класса GetCursOnDateXMLResponse. Определение этих классов находится в файле default.rb:
require 'xsd/qname'

...

# {http://web.cbr.ru/}GetCursOnDateXML
#   on_date - SOAP::SOAPDateTime
class GetCursOnDateXML
  attr_accessor :on_date

  def initialize(on_date = nil)
    @on_date = on_date
  end
end

# {http://web.cbr.ru/}GetCursOnDateXMLResponse
#   getCursOnDateXMLResult -
#   GetCursOnDateXMLResponse::GetCursOnDateXMLResult
class GetCursOnDateXMLResponse

  # inner class for member: GetCursOnDateXMLResult
  # {http://web.cbr.ru/}GetCursOnDateXMLResult
  class GetCursOnDateXMLResult
    attr_reader :__xmlele_any

    def set_any(elements)
      @__xmlele_any = elements
    end

    def initialize
      @__xmlele_any = nil
    end
  end

  attr_accessor :getCursOnDateXMLResult

  def initialize(getCursOnDateXMLResult = nil)
    @getCursOnDateXMLResult = getCursOnDateXMLResult
  end
end

...
С классом GetCursOnDateXML все достаточно очевидно. В его конструктор достаточно передать дату, что мы и делаем в строке 26 листинга get_curs.rb. Класс GetCursOnDateXMLResponse выглядит несколько сложнее. В нем определен метод getCursOnDateXMLResult который, судя по всему, и возвращает результат. Но в каком формате? Давайте заглянем в WSDL-файл и найдем там описание типа GetCursOnDateXMLResult:
...
<s:element minOccurs="0" maxOccurs="1" name="GetCursOnDateXMLResult">
  <s:complexType mixed="true">
    <s:sequence>
      <s:any/>
    </s:sequence>
  </s:complexType>
</s:element>
...
Из этого фрагмента можно заключить, что GetCursOnDateXMLResult - это список "чего угодно" (s:any). В таких ситуациях на помощь приходит включение отладочного вывода (см. строку 23 листинга get_curs.rb) и irb - интерактивная консоль Ruby. При помощи irb можно наблюдать как исполняется код по мере его написания.

Итак, запускаем irb (из директории где находятся наши файлы), загружаем библиотеку SOAP4R и клиентские заглушки:

$ irb
irb(main):001:0> require 'rubygems'

=> true

irb(main):002:0> require_gem 'soap4r'

=> true

irb(main):003:0> require 'defaultDriver.rb'

=> true

irb(main):004:0>
Создаем объект-драйвер для работы с веб-сервисом и включаем отладочный вывод:
irb(main):004:0> serv = DailyInfoSoap.new

=> #<DailyInfoSoap:#<SOAP::RPC::Proxy:http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx>>

irb(main):005:0> serv.wiredump_dev = STDERR

=> #<IO:0xb7c4ff60>

irb(main):006:0>
Далее создаем запрос с текущей датой и отправляем его на сервер:
irb(main):006:0> request = GetCursOnDateXML.new(DateTime.now)

=> #<GetCursOnDateXML:0xb76797d0 @on_date=#<DateTime: 70695916331796971/28800000000,1/6,2299161>>

irb(main):007:0> response = serv.getCursOnDateXML(request)

Wire dump:

= Request

! CONNECT TO www.cbr.ru:80
! CONNECTION ESTABLISHED
POST /DailyInfoWebServ/DailyInfo.asmx HTTP/1.1
SOAPAction: "http://web.cbr.ru/GetCursOnDateXML"
Content-Type: text/xml; charset=utf-8
User-Agent: SOAP4R/1.5.8 (/187, ruby 1.8.6 (2007-03-13) [i586-linux-gnu])
Date: Tue, 09 Sep 2008 19:36:45 GMT
Content-Length: 405
Host: www.cbr.ru

<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<n1:GetCursOnDateXML xmlns:n1="http://web.cbr.ru/">
 <n1:On_date>2008-09-09T23:36:35.390913+04:00</n1:On_date>
</n1:GetCursOnDateXML>
</env:Body>
</env:Envelope>

= Response

HTTP/1.1 200 OK
Date: Tue, 09 Sep 2008 19:40:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: text/xml; charset=utf-8
Content-Length: 7601

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas. xmlsoap.org/soap/envelope/"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance "
          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetCursOnDateXMLResponse xmlns="http://web.cbr.ru/">
 <GetCursOnDateXMLResult>
   <ValuteData xmlns="">
     <ValuteCursOnDate>
       <Vname>Австралийский доллар</Vname>
       <Vnom>1</Vnom>
       <Vcurs>21.0261</Vcurs>
       <Vcode>36</Vcode>
       <VchCode>AUD</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Фунт стерлингов Соединенного королевства</Vname>
       <Vnom>1</Vnom>
       <Vcurs>44.9826</Vcurs>
       <Vcode>826</Vcode>
       <VchCode>GBP</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Белорусский рубль</Vname>
       <Vnom>1000</Vnom>
       <Vcurs>11.9615</Vcurs>
       <Vcode>974</Vcode>
       <VchCode>BYR</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Датская крона</Vname>
       <Vnom>10</Vnom>
       <Vcurs>48.5829</Vcurs>
       <Vcode>208</Vcode>
       <VchCode>DKK</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Доллар США</Vname>
       <Vnom>1</Vnom>
       <Vcurs>25.2626</Vcurs>
       <Vcode>840</Vcode>
       <VchCode>USD</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Евро</Vname>
       <Vnom>1</Vnom>
       <Vcurs>36.2670</Vcurs>
       <Vcode>978</Vcode>
       <VchCode>EUR</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Исландская крона</Vname>
       <Vnom>100</Vnom>
       <Vcurs>28.8435</Vcurs>
       <Vcode>352</Vcode>
       <VchCode>ISK</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Казахский тенге</Vname>
       <Vnom>100</Vnom>
       <Vcurs>21.1120</Vcurs>
       <Vcode>398</Vcode>
       <VchCode>KZT</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Канадский доллар</Vname>
       <Vnom>1</Vnom>
       <Vcurs>23.8642</Vcurs>
       <Vcode>124</Vcode>
       <VchCode>CAD</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Китайский юань Жэньминьби</Vname>
       <Vnom>10</Vnom>
       <Vcurs>36.9304</Vcurs>
       <Vcode>156</Vcode>
       <VchCode>CNY</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Норвежская крона</Vname>
       <Vnom>10</Vnom>
       <Vcurs>45.2719</Vcurs>
       <Vcode>578</Vcode>
       <VchCode>NOK</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>СДР (специальные права заимствования)</Vname>
       <Vnom>1</Vnom>
       <Vcurs>39.0691</Vcurs>
       <Vcode>960</Vcode>
       <VchCode>XDR</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Сингапурский доллар</Vname>
       <Vnom>1</Vnom>
       <Vcurs>17.7668</Vcurs>
       <Vcode>702</Vcode>
       <VchCode>SGD</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Новая турецкая лира</Vname>
       <Vnom>1</Vnom>
       <Vcurs>20.7564</Vcurs>
       <Vcode>949</Vcode>
       <VchCode>TRY</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Украинская гривна</Vname>
       <Vnom>10</Vnom>
       <Vcurs>53.5225</Vcurs>
       <Vcode>980</Vcode>
       <VchCode>UAH</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Шведская крона</Vname>
       <Vnom>10</Vnom>
       <Vcurs>38.3377</Vcurs>
       <Vcode>752</Vcode>
       <VchCode>SEK</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Швейцарский франк</Vname>
       <Vnom>1</Vnom>
       <Vcurs>22.5962</Vcurs>
       <Vcode>756</Vcode>
       <VchCode>CHF</VchCode>
     </ValuteCursOnDate>
     <ValuteCursOnDate>
       <Vname>Японская иена</Vname>
       <Vnom>100</Vnom>
       <Vcurs>23.2653</Vcurs>
       <Vcode>392</Vcode>
       <VchCode>JPY</VchCode>
     </ValuteCursOnDate>
   </ValuteData>
 </GetCursOnDateXMLResult>
</GetCursOnDateXMLResponse>
</soap:Body>
</soap:Envelope>
=> #<GetCursOnDateXMLResponse:0xb7658c74 @getCursOnDateXMLResult=#<GetCursOnDate
...
В отладочном выводе хорошо видно как вызов метода трансформируется в SOAP-сообщение. Ответ также очень наглядный: мы видим последовательность вложенных тегов: GetCursOnDateXMLResponse, GetCursOnDateXMLResult и ValuteData. Внутри ValuteData находится список тегов ValuteCursOnDate по одному на каждую валюту. Названия атрибутов также вполне ожидаемые - Vname, Vnom, Vcurs, Vcode и VchCode. Но как нам получить доступ к этим данным из кода Ruby? Для ответа на этот вопрос давайте выведем имена всех доступных методов объекта response в алфавитном порядке:
irb(main):008:0> response.methods.sort

=> ["==", "===", "=~", "__id__", "__send__", "class", "clone", "dclone",
"display", "dup", "eql?", "equal?", "extend", "freeze", "frozen?", "gem",
"getCursOnDateXMLResult", "getCursOnDateXMLResult=", "hash", "id", "inspect",
"instance_eval", "instance_of?", "instance_variable_defined?",
"instance_variable_get", "instance_variable_set", "instance_variables", "is_a?",
"kind_of?", "method", "methods", "nil?", "object_id", "private_methods",
"protected_methods", "public_methods", "require", "require_gem", "respond_to?", "send",
"singleton_methods", "taint", "tainted?", "to_a", "to_s", "type", "untaint"]

irb(main):009:0>
Обратите внимание на метод getCursOnDateXMLResult. Посмотрим, что он возвращает:
irb(main):009:0> response.getCursOnDateXMLResult.methods.sort

=> ["==", "===", "=~", "__id__", "__send__", "__xmlele_any", "class", "clone",
"dclone", "display", "dup", "eql?", "equal?", "extend", "freeze", "frozen?",
"gem", "hash", "id", "inspect", "instance_eval", "instance_of?",
"instance_variable_defined?", "instance_variable_get", "instance_variable_set",
"instance_variables", "is_a?", "kind_of?", "method", "methods", "nil?",
"object_id", "private_methods", "protected_methods", "public_methods",
"require", "require_gem", "respond_to?", "send", "set_any", "singleton_methods",
"taint", "tainted?", "to_a", "to_s", "type", "untaint", "valuteData","valuteData="]

irb(main):010:0>
В списке имеется метод valuteData. Посмотрим что внутри:
irb(main):010:0> response.getCursOnDateXMLResult.valuteData.methods.sort

=> ["==", "===", "=~", "[]", "[]=", "__add_xmlele_value", "__id__", "__send__",
"__xmlattr", "__xmlele", "class", "clone", "dclone", "display", "dup", "eql?",
"equal?", "extend", "freeze", "frozen?", "gem", "hash", "id", "inspect",
"instance_eval", "instance_of?", "instance_variable_defined?",
"instance_variable_get", "instance_variable_set", "instance_variables", "is_a?",
"kind_of?", "marshal_dump", "marshal_load", "method", "methods", "nil?",
"object_id", "private_methods", "protected_methods", "public_methods",
"require", "require_gem", "respond_to?", "send", "singleton_methods", "taint",
"tainted?", "to_a", "to_s", "type", "untaint", "valuteCursOnDate","valuteCursOnDate="]
irb(main):011:0>
Мы почти у цели. Посмотрим, какой объект возвращает метод valuteCursOnDate:
irb(main):011:0> response.getCursOnDateXMLResult.valuteData.valuteCursOnDate.class

=> Array

irb(main):012:0> response.getCursOnDateXMLResult.valuteData.valuteCursOnDate.length

=> 18
irb(main):013:0>
Ага! Этот метод возвращает массив из 18 элементов. По всей видимости это и есть список валют. Для проверки нашей догадки, возьмем какой-нибудь элемент массива и посмотрим как он выглядит:
irb(main):013:0> response.getCursOnDateXMLResult.valuteData.valuteCursOnDate[4].methods.sort

=> ["==", "===", "=~", "[]", "[]=", "__add_xmlele_value", "__id__", "__send__",
"__xmlattr", "__xmlele", "class", "clone", "dclone", "display", "dup", "eql?",
"equal?", "extend", "freeze", "frozen?", "gem", "hash", "id", "inspect",
"instance_eval", "instance_of?", "instance_variable_defined?",
"instance_variable_get", "instance_variable_set", "instance_variables", "is_a?",
"kind_of?", "marshal_dump", "marshal_load", "method", "methods", "nil?",
"object_id", "private_methods", "protected_methods", "public_methods",
"require", "require_gem", "respond_to?", "send", "singleton_methods", "taint",
"tainted?", "to_a", "to_s", "type", "untaint", "vchCode", "vchCode=", "vcode",
"vcode=", "vcurs", "vcurs=", "vname", "vname=", "vnom", "vnom="]

irb(main):014:0> response.getCursOnDateXMLResult.valuteData.valuteCursOnDate[4].vchCode

=> "USD"

irb(main):015:0> response.getCursOnDateXMLResult.valuteData.valuteCursOnDate[4]['VchCode']

=> "USD"
irb(main):016:0>
Действительно, каждый элемент массива соответствует определенной валюте. К атрибутам можно обратиться либо при помощи методов vname, vnom, vcurs, vcode, vchCode либо как к элементам хеша. Названия ключей при этом совпадают с названиями тегов в ответном XML-файле: Vname, Vnom, Vcurs, Vcode и VchCode. Теперь код тестовой программы становится очевидным: мы формируем запрос, отправляем его на сервер, получаем ссылку на массив валют, а затем бежим по этому массиву и выводим значения атрибутов. Вот и все!

Отмечу, что в более сложных ситуациях неоценимую помощь оказывают инструменты для отладки веб-сервисов, например, soapUI. При помощи этой программы можно вручную формировать SOAP-запросы и анализировать ответ от сервера.

Заключение

Веб-сервисы - это идеальное решение для интеграции программных систем. По сути, это единый язык на котором могут говорить приложения, написанные разными людьми на разных языках программирования и работающих на разных программно-аппаратных платформах. Сама технология базируется на открытых стандартах и имеет хорошую поддержку во всех современных языках программирования. Не исключение и Ruby. Как мы смогли убедиться, код на Ruby получается очень простым, компактным и выразительным.

Размещение рекламы — тел. +7 495 4119920, ICQ 232284597

Подписка на новости IT-портала CITForum.ru
(библиотека, CITKIT.ru, CitCity)

Новые публикации:

24 декабря

CITKIT.ru:

  • Новогодние поздравления
  • Сергей Кузнецов. Цикл Операционные системы: Ностальгия по будущему:

  • Алексей Федорчук. OpenSolaris 2008.11 Release

  • Сергей Голубев:

  • Евгений Чайкин aka StraNNik (Блогометки):

    17 декабря

  • С.Д.Кузнецов. Базы данных. Вводный курс

    10 декабря

    CITKIT.ru:

  • OpenSolaris 2008.11 Release

  • Альтернативные ОС: две грустные истории (С.Кузнецов)
  • Nokia N810 — доведение до ума
  • CitCity:

  • Платформа 2009: заоблачные перспективы Microsoft

    4 декабря

  • Лекция С.Д.Кузнецова Понятие модели данных. Обзор разновидностей моделей данных

    CITKIT.ru:

  • OpenSolaris 2008.11 Release. Первые впечатления

  • Linux vs FreeBSD: продолжим "Священные войны"?

  • Nokia N810 as is

  • Индульгенция для FOSS

  • Друзья СПО'2008

    26 ноября

  • Нечеткое сравнение коллекций: семантический и алгоритмический аспекты

    CitCity:

    CITKIT.ru:

  • Глава из книги А.Федорчука
    Сага о FreeBSD:
  • 19 ноября

  • Проблемы экономики производства крупных программных продуктов

  • Язык модификации данных формата XML функциональными методами

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    Заметки к книге:

  • FreeBSD: монтирование сменных устройств и механизм HAL
  • Текстовый редактор ee

    12 ноября

  • Правило пяти минут двадцать лет спустя, и как флэш-память изменяет правила (Гоц Грейф, перевод: Сергей Кузнецов)

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:
  • OSS в России: взгляд правоведа (В.Житомирский)

  • Новая статья из цикла С.Голубева "Железный марш":

    29 октября

  • О некоторых задачах обратной инженерии

  • Веб-сервисы и Ruby

  • Тестирование web-приложений с помощью Ruby

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

  • PuppyRus Linux - беседа с разработчиком (С.Голубев)

  • Сергей Кузнецов. Заметка не про Linux

    22 октября

  • Обзор методов описания встраиваемой аппаратуры и построения инструментария кросс-разработки

    CITKIT.ru:

  • Сергей Кузнецов. Почему я равнодушен к Linux

  • Глава из книги А.Федорчука
    Сага о FreeBSD:
  • Что надо иметь
    3. Базовые познания

    CitCity:

  • Управление IT-инфраструктурой на основе продуктов Microsoft

    15 октября

  • Методы бикластеризации для анализа интернет-данных

    CitCity:

  • Разъемы на ноутбуках: что они дают и зачем их так много?
  • AMD Puma и Intel Centrino 2: кто лучше?

    CITKIT.ru:

  • Новый цикл статей С.Голубева
    Железный марш:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    8 октября

  • Автоматизация тестирования web-приложений, основанных на скриптовых языках
  • Опыт применения технологии Azov для тестирования библиотеки Qt3

    Обзоры журнала Computer:

  • SOA с гарантией качества
  • Пикоджоуль ватт бережет
  • ICT и всемирное развитие

    CitCity:

  • Пиррова победа корпорации Microsoft

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    Статья из архива:

  • Я живу в FreeBSD (Вадим Колонцов)

    Новые Блогометки:

  • Перекройка шаблона Blogger или N шагов к настоящему
  • Blogger. Comment style
  • Screenie или глянцевый снимок экрана

    2 октября

    CITKIT.ru:

  • Сага о FreeBSD (А. Федорчук)

    Zenwalk: пакет недели

  • Банинг — интеллектуальное развлечение (С.Голубев)

    CitCity:

    25 сентября

  • Клермонтский отчет об исследованиях в области баз данных

    CITKIT.ru:

  • Пользователям просьба не беспокоиться... (В.Попов)

  • Снова про ZFS: диск хорошо, а два лучше
  • Командная оболочка tcsh (А.Федорчук)

    Zenwalk: пакет недели

    17 сентября

  • T2C: технология автоматизированной разработки тестов базовой функциональности программных интерфейсов
  • Технология Azov автоматизации массового создания тестов работоспособности

    CITKIT.ru:

  • FreeBSD: ZFS vs UFS, и обе-две — против всех (А.Федорчук)

    Zenwalk: пакет недели

  • Дачнет — практика без теории (С.Голубев)

    10 сентября

  • За чем следить и чем управлять при работе приложений с Oracle
  • Планировщик заданий в Oracle
    (В.Пржиялковский)

    CITKIT.ru:

  • Microsoft: ответный "боян" (С.Голубев)

  • Причуды симбиоза, или снова "сделай сам" (В.Попов)

  • Файловые системы современного Linux'а: последнее тестирование
  • Zsh. Введение и обзор возможностей
    (А.Федорчук)

    Описания пакетов Zenwalk: Zsh, Thunar, Thunar-bulk-rename, Xfce4-places-plugin, Xfce4-fsguard-plugin

    Блогометки:

  • Google Chrome
  • Лончер для ASUS Eee PC 701

    3 сентября

    CITKIT.ru:

  • Заметки о ядре (А.Федорчук):

    Добавлены описания пакетов Zenwalk: Galculator, Screenshot, Gnumeric, Pidgin

    В дискуссинном клубе:

  • И еще о Википедии и Google Knol

  • Лекция для начинающего линуксоида (С.Голубев)

    26 августа

  • Транзакционная память (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • Открыт новый проект Zenwalk: пакет недели

  • Статья Текстовые процессоры и их быстродействие: конец еще одной легенды?

    21 августа

    CITKIT.ru:

  • Почему школам следует использовать только свободные программы (Ричард Столлман)
  • Беседа Сергея Голубева с учителем В.В.Михайловым

  • Википедия или Гуглезнание? Приглашение к обсуждению (Алексей Федорчук)
  • Народная энциклопедия от Google (StraNNik)

  • Обзор Mandriva 2009.0 Beta 1 Thornicrofti
  • Новичок в Линукс: Оптимизируем Mandriva 2008.1

  • Книга Zenwalk. Приобщение к Linux:

    13 августа

    CitCity:

  • Мирный Atom на службе человеку. Обзор платы Intel D945GCLF с интегрированным процессором
  • Обзор процессоров Intel Atom 230 на ядре Diamondville

  • iPhone - год спустя. Скоро и в России?

    CITKIT.ru:

  • Интермедия 3.4. GRUB: установка и настройка (из книги Zenwalk. Приобщение к Linux)

    6 августа

  • СУБД с хранением данных по столбцами и по строкам: насколько они отличаются в действительности? (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • Интермедия 2.2. Что неплохо знать для начала (из книги Zenwalk. Приобщение к Linux)

  • И снова про шрифты в Иксах (А.Федорчук)

  • 20 самых быстрых и простых оконных менеджеров для Linux

  • Дело о трех миллиардах (С.Голубев)

    30 июля

  • OLTP в Зазеркалье (Пересказ: С. Кузнецов)

    CitCity:

  • Будущее BI в облаках?
  • Тиражные приложения и заказная разработка. Преимущества для заказчика
  • Дискуссия со сторонниками заказной разработки

    CITKIT.ru:

  • Новые главы книги Zenwalk. Приобщение к Linux:
  • Глава 8. Пакеты: средства установки, системы управления, системы построения
  • Глава 9. Zenwalk: репозитории, пакеты, методы установки

    23 июля

    CITKIT.ru:

  • Все против всех. 64 vs 32, Intel vs AMD, tmpfs vs ext3
  • Две головы от Intel

  • Zenwalk: обзор штатных приложений (глава из книги "Zenwalk. Приобщение к Linux")

  • Нормально, Григорий...

    16 июля

    Обзоры журнала Computer:

  • Перспективы и проблемы программной инженерии в XXI веке
  • Большие хлопоты с большими объемами данных
  • Перспективы наноэлектроники

    CITKIT.ru:

  • Интермедия о лицензиях (А.Федорчук. "Zenwalk. Приобщение к Linux")

  • Есть ли будущее у KDE?

  • Linux в школе: альтернативный вариант в задачах

  • Шифр (приключения агента Никодима)

    10 июля

    CITKIT.ru:

  • Новые разделы книги А. Федорчука Zenwalk. Приобщение к Linux:
  • Интермедия вступительная. Linux или GNU/Linux? Как вас теперь называть?
  • Глава 5. Среда Xfce
  • Глава 6. Xfce: приложения и плагины

  • ZUR (Zenwalk User Repository) FAQ

    2 июля

  • Персистентность данных в объектно-ориентированных приложениях (С. Кузнецов)

    CITKIT.ru:

  • Новые разделы книги А. Федорчука Zenwalk. Приобщение к Linux:
  • Интермедия 1.2. Дорога к Zenwalk'у. Период бури и натиска
  • Интермедия 3.3. Немного о Linux'е и "железе"
  • Глава 4. Настройка: инструментами и руками
  • Интермедия 4.1. Zenpanel и конфиги: поиски корреляции

  • Интервью с Жан-Филиппом Гийоменом, создателем дистрибутива Zenwalk

  • Linux в школе: первые итоги (С. Голубев)

    25 июня

    CITKIT.ru:

  • Zenwalk. Приобщение к Linux (А. Федорчук)

  • Логика и риторика (С.Голубев)

  • Технология Tru64 AdvFS

  • Ханс Райзер предлагает отвести полицейских к телу Нины

    18 июня

  • Проекты по управлению данными в Google (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • ОС и поддержка "железа": мифы и реальность (А. Федорчук)

  • Linux в школе: другие дистрибутивы

  • Пинок (С. Голубев)

    4 июня

  • Ландшафт области управления данными: аналитический обзор (С. Кузнецов)

    CITKIT.ru:

  • Linux в школе: слово заинтересованным лицам

  • SlackBuild: пакеты своими руками

  • Linux от компании Novell. Установка и обзор openSUSE Linux

    Все публикации >>>




  • IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

    Информация для рекламодателей PR-акции, размещение рекламы — тел. +7 495 4119920, ICQ 232284597 Пресс-релизы — pr@citcity.ru
    Послать комментарий
    Информация для авторов
    Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
    Copyright © 1997-2000 CIT, © 2001-2007 CIT Forum
    Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...