Для того чтобы начать создавать и использовать 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> ЛИСТИНГ 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-запроса - решать вам: приведенное выше решение поддерживает оба способа.
|