Web-сервис за 10 минут
 

Для того чтобы начать создавать и использовать Web-сервисы, нет необходимости дожидаться выхода финальной версии Microsoft .NET - такие сервисы могут быть созданы уже сегодня. Например, чтобы создать новую модель вашего Web-приложения, которая будет совместима с концепциями сервисоориентированного Web, достаточно решить, какие части приложения будут реализованы в виде сервисов, определить интерфейсы и задать спецификацию выходной информации. В этой статье мы рассмотрим, как создать простой Web-сервис средствами Active Server Pages (ASP), и напишем код сервера и потребителя.

По определению Web-сервис - это код, доступный по протоколу HTTP и возвращающий информацию в формате XML. Идея создания Web-сервисов, решающих многие стандартные задачи, очень привлекательна - в этом случае мы получаем программируемые Web-приложения, которые могут располагаться где угодно и работать на любых платформах. Отметим, что «каноническое» определение Web-сервиса включает поддержку протокола SOAP для реализации возможностей вызова удаленных объектов, а также протоколов DISCO и UDDI для реализации возможностей поиска сервисов как на одном Web-узле, так и в Internet в целом. Сервис, который мы создадим с помощью данной статьи, не обладает такой функциональностью; как уже было сказано выше, нашей задачей будет тестирование концепции сервиса как такового.

Сервер

Сервис, реализованный в нашем примере, будет выполнять конвертацию из одной валюты в другую и возвращать собственно результат конвертации, текущий курс и текстовую строку, содержащую результат конвертации.

При вызове нашего сервиса мы указываем три параметра: Amount, From и To. Первый параметр указывает сумму, которую необходимо перевести, второй и третий - коды валюты. Мы используем коды валюты, определенные стандартом 4217. Данные о текущем курсе содержатся в таблице SQL Server, которая имеет формат, показанный в таблице.

Curr CurrName USDUnit UnitsUSD
USD United States Dollars 1.0 1.0
ATS Austria Schillings 6.5256499999999995E-2 15.3241
BEF Belgium Francs 2.2259600000000001E-2 44.924500000000002
GBP United Kingdom Pounds 1.42357 0.70245999999999997
EUR Euros 0.897949 1.11365
FRF France Francs 0.13689100000000001 7.3050600000000001
DEM Germany Deutsche Marks 0.45911400000000002 2.1781100000000002
ITL Italy Lire 0.000463752 2156.3299999999999
ESP Spain Pesetas 5.3967800000000003E-3 185.29599999999999
CHF Switzerland Francs 0.586113 1.7061599999999999

Таблица обновляется раз в день на основе данных, поступающих от одного из провайдеров финансовой информации (еще один Web-сервис!).

Как мы отмечали выше, наш Web-cервис будет реализован средствами Active Server Pages. Ниже мы детально рассмотрим ASP-код, реализующий данный сервис.

Поскольку сервис должен возвращать данные в формате XML, мы должны указать тип возвращаемой информации:

Response.ContentType = "text/xml"

Далее мы обрабатываем переданные потребителем параметры (в нашем случае параметры передаются как часть URL, но могут передаваться и внутри HTTP-запроса).

Amount = Request.QueryString("Amount") CurrFrom = Request.QueryString ("From") CurrTo = Request.QueryString ("To")

Мы готовы обратиться к базе данных за информацией о текущем курсе. Для этого используем стандартные объекты ADO и простой SQL-запрос, возвращающий набор, состоящий из двух записей:

Set Conn = Server.CreateObject("ADODB.Connection") Conn.Provider = "SQLOLEDB" ProvStr = "Server=jupiter;Database=WebDemo;Trusted_Connection=yes" Conn.Open ProvStr   Set RS = Server.CreateObject("ADODB.Recordset") Query = "SELECT * FROM Curr WHERE Curr='" & CurrFrom & _  "' OR Curr='" & CurrTo & "'"   RS.ActiveConnection = Conn RS.Source = Query RS.Open   DataTo = RS("USDUnit")   RS.MoveNext   DataFrom = RS("USDUnit")   DataTo = RS("USDUnit") RS.Close   Conn.Close Set Conn = Nothing 

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

Result = FormatNumber(Amount * (DataFrom / DataTo), 2)

Здесь мы используем функцию FormatNumber для задания числа символов после запятой.

Итак, мы собрали всю информацию, необходимую для создания XML-документа, передаваемого потребителю. Можно начать создавать этот документ. В нашем примере мы будем использовать Microsoft XML DOM, хотя можно обойтись и простой конкатенацией строк.

' Начнем создавать XML-документ     Set XMLDoc = Server.CreateObject("Microsoft.XMLDOM")     Set pi = XMLDoc.createProcessingInstruction("xml",   " version=""1.0"" encoding=""Windows-1252""")   XMLDoc.appendChild(pi)   ' Главная ветвь     Set mainNode = XMLDoc.createElement("conversion")  XMLDoc.appendChild(mainNode) 

Приведенный выше код создает экземпляр Microsoft XML DOM. После этого, используя метод createProcessingInstruction, мы создаем заголовок документа и добавляем его к нашему документу. Далее создаем главную ветвь - <conversion> и также добавляем ее к документу. Вся информация будет храниться в дочерних ветвях данной ветви. Чтобы добавить одну или более дочерних ветвей, мы создадим следующую функцию:

Sub AddSubNode(Parent, Name, Value)     Set subNode = XMLDoc.createElement(Name)   Parent.appendChild(subNode)   subNode.appendChild(XMLDoc.createTextNode(Value))   End Sub 

а затем воспользуемся ею для генерации дочерних ветвей нашего документа:

AddSubNode mainNode, "from",    CurrFrom AddSubNode mainNode, "to",      CurrTo AddSubNode mainNode, "amount",  Amount AddSubNode mainNode, "result",  Result AddSubNode mainNode, "usdFrom", DataFrom AddSubNode mainNode, "usdTo",   DataTo AddSubNode mainNode, "rate",    FormatNumber(DataFrom / DataTo, 4) AddSubNode mainNode, "text", CStr(Amount) & " " & CurrFrom & _  " = " & Result & " " & CurrTo 

И наконец, мы можем вернуть готовый документ потребителю:

Response.Write XMLDoc.XML

Если в качестве потребителя мы будем использовать браузер Microsoft Internet Explorer и зададим следующий адрес (перевести 20 швейцарских франков в евро):

http://jupiter/demos/service/server.asp?Amount=20&From=CHF&To=EUR

то получим следующий XML-документ:

<?xml version="1.0"?> <conversion>   <from>CHF</from>  <to>EUR</to>   <amount>20</amount>  <result>13.05</result>   <usdFrom>0.586113</usdFrom>   <usdTo>0.897949</usdTo>   <rate>0.6527</rate>  <text>20 CHF = 13.05 EUR</text> </conversion> 

Microsoft Internet Explorer отобразит этот документ, как показано на рис.1.



Рис.1.

 ЛИСТИНГ 1. <% Response.ContentType = "text/xml" '-------------------------------------- ' Web Service Provider ' ' Parameters: ' ' Amount = Amount to convert ' From = Source Currency ' To = Target Currency '-------------------------------------- Sub AddSubNode(Parent, Name, Value) Set subNode = XMLDoc.createElement(Name) Parent.appendChild(subNode) subNode.appendChild(XMLDoc.createTextNode(Value)) End Sub Amount = Request.QueryString("Amount") CurrFrom = Request.QueryString ("From") CurrTo = Request.QueryString ("To") Set Conn = Server.CreateObject("ADODB.Connection") Conn.Provider = "SQLOLEDB" ProvStr = "Server=jupiter;Database=WebDemo; Trusted_Connection=yes" Conn.Open ProvStr Set RS = Server.CreateObject("ADODB.Recordset") Query = "SELECT * FROM Curr WHERE Curr='" & CurrFrom & _ "' OR Curr='" & CurrTo & "'" RS.ActiveConnection = Conn RS.Source = Query RS.Open DataTo = RS("USDUnit") RS.MoveNext DataFrom = RS("USDUnit") RS.Close Conn.Close Set Conn = Nothing Result = FormatNumber(Amount * (DataFrom / DataTo), 2) ' Начнем создавать XML-документ Set XMLDoc = Server.CreateObject("Microsoft.XMLDOM") Set pi = XMLDoc.createProcessingInstruction("xml", " version=""1.0"" encoding=""Windows-1252""") XMLDoc.appendChild(pi) ' Главная ветвь Set mainNode = XMLDoc.createElement("conversion") XMLDoc.appendChild(mainNode) AddSubNode mainNode, "from", CurrFrom AddSubNode mainNode, "to", CurrTo AddSubNode mainNode, "amount", Amount AddSubNode mainNode, "result", Result AddSubNode mainNode, "usdFrom", DataFrom AddSubNode mainNode, "usdTo", DataTo AddSubNode mainNode, "rate", FormatNumber(DataFrom / DataTo, 4) AddSubNode mainNode, "text", CStr(Amount) & " " & CurrFrom & _ " = " & Result & " " & CurrTo Response.Write XMLDoc.XML Set mainNode = Nothing Set XMLDoc = Nothing %> 

После того как мы реализовали наш Web-сервис, мы должны написать код для потребителя этого сервиса. Рассмотрим этот вопрос в следующем разделе.

Потребитель

Как мы определили в начале этой статьи, потребитель Web-сервиса должен посылать сервису HTTP-запрос и получать результат в виде XML-документа. После этого потребитель должен обработать полученный XML-документ и извлечь из него необходимые данные.

Для посылки HTTP-запроса мы будем использовать методы, реализованные в объекте ServerXMLHTTP, который является частью Microsoft XML DOM (см. врезку), а для обработки XML-документа - методы объекта DOMDocument.

Начнем с того, что создадим экземпляры двух упомянутых выше объектов:

Set HTTPReq = Server.CreateObject("MSXML2.ServerXMLHTTP") Set XMLDoc = Server.CreateObject("MSXML2.DOMDocument")

Далее мы генерируем HTTP-запрос - этот процесс состоит из вызова двух методов объекта ServerXMLHTTP - Open для задания метода передачи информации и адреса и Send для непосредственной отсылки запроса.

HTTPReq.Open "POST", "http://jupiter/demos/service/server.asp" & _     "?Amount=200&From=FRF&To=USD", False HTTPReq.Send 

Возвращаемый нашим сервисом XML-документ может быть получен либо как значение свойства ResponseXML, либо - как значение свойства ResponseText. И в том и в другом случае мы загружаем этот документ в экземпляр объекта DOMDocument.

XMLDoc.LoadXML HTTPReq.ResponseText

Объект произведет необходимую обработку XML-документа, после чего мы сможем извлечь из него данные:

Set Node = XMLDoc.selectSingleNode("/conversion/text") Response.Write Node.Text

Отметим, что в вышеприведенном фрагменте мы извлекаем текстовую строку, которая для нашего примера будет выглядеть так:

20 CHF = 13.05 EUR

Помимо этого при обращении к ветви result мы можем получить только результат конвертации, а при обращении к ветви rate - текущий курс.

Полный код, реализующий потребителя нашего Web-сервиса, приведен в листинге 2.

ЛИСТИНГ 2 <% '------------------------------ ' Currency Service Consumer '------------------------------ Set HTTPReq = Server.CreateObject("MSXML2.ServerXMLHTTP") Set XMLDoc = Server.CreateObject("MSXML2.DOMDocument") HTTPReq.Open "POST", "http://jupiter/demos/service/server.asp" & _ "?Amount=200&From=FRF&To=USD", False HTTPReq.Send XMLDoc.LoadXML HTTPReq.ResponseText Set Node = XMLDoc.selectSingleNode("/conversion/text") Response.Write Node.Text Set Node = Nothing Set HTTPReq = Nothing Set XMLDoc = Nothing %> 

Завершая обсуждение реализации потребителя Web-сервиса, отметим, что можно передавать параметры и как часть HTTP-запроса (а не как часть URL). Для этого необходимо изменить код генерации HTTP-запроса на следующий:

HTTPReq.Open "POST", "http://jupiter/demos/service/curr2.asp", False   HTTPReq.SetRequestHeader "Amount", "20" HTTPReq.SetRequestHeader "From",   "FRF" HTTPReq.SetRequestHeader "To", "USD"   HTTPReq.Send 

Поскольку в этом случае параметры передаются как часть HTTP-запроса, необходимо также изменить код обработки параметров в сервере:

Amount = Request.ServerVariables("HTTP_Amount") CurrFrom = Request("HTTP_From") CurrTo = Request("HTTP_To")

Какой из вариантов передачи параметров использовать в том или ином случае - передавать параметры через URL либо внутри HTTP-запроса - решать вам: приведенное выше решение поддерживает оба способа.

Заключение

В данной статье мы рассмотрели возможности создания Web-сервиса и потребителя данного сервиса, чтобы уже сегодня можно было начать предварительное тестирование новой архитектурной модели Web, которая появится в ближайшие годы.

 
Автор: Алексей Федоров
 
Оригинал статьи: http://www.woweb.ru/publ/60-1-0-207