Web-сервис представляет собой основанный на Web интерфейс программирования приложений (API - application programming interface), доступ к которому осуществляется по протоколу HTTP (Hypertext Transfer Protocol – протокол передачи гипертекста). На стороне сервера с помощью языка WSDL (Web Services Description Language – язык описания Web-сервисов), являющегося разновидностью XML (Extensible Markup Language – расширяемый язык разметки), описываются определенные операции. Спецификация для обмена информацией между клиентом и сервером называется SOAP (Simple Object Access Protocol – простой протокол доступа к объектам). В мире Web-сервисов действительно очень много сокращений.
С точки зрения реальных задач Web-сервисы позволяют организовать централизованный обмен информацией. Как следует из самого названия, они предоставляют доступ к сервису клиентам, которые могут находиться в любой точке земного шара. Например, посредством Web-сервисов можно получить последние заголовки новостей, список новинок книжного Интернет-магазина или исторические отчеты о рыбалке в определенном регионе. Из названия этой технологии также следует, что часто эта информация выводится на Web-сайтах, будь то профессиональные журналистские сайты или персональные блоги.
Dojo – это открытый набор инструментов разработки пользовательского интерфейса на JavaScript, облегчающий быструю разработку JavaScript-приложений. Его можно рассматривать как набор JavaScript-библиотек, упрощающих и ускоряющих написание кода JavaScript.
Один из главных компонентов инфраструктуры Dojo называется Dojo Base. Эта часть библиотеки Dojo занимается тонкостями обработки событий, вызовами Ajax (Asynchronous JavaScript + XML), запросами каскадных таблиц стилей (CSS - Cascading Style Sheets), графическими эффектами и многим другим.
Помимо Dojo Base, следует упомянуть виджет Dijit — один из самых популярных элементов Dojo. Этот виджет представляет собой набор клиентских компонентов многократного использования, которые можно буквально перетаскивать в свое приложение. Для настройки внешнего вида виджетов в вашем приложении в большинстве случаев достаточно сделать лишь несколько простых изменений в конфигурации.
Конструируем приложение с помощью Dojo и Web-сервиса
Совет директоров компании FishinHole.com решил, что предоставление доступа к каталогу компании посредством Web-сервиса поможет продвижению ее продуктов в Web и даст ей конкурентное преимущество. Совет директоров попросил вас к завтрашнему дню создать Web-сервис и прототип, иллюстрирующий работу с ним с помощью простой Web-страницы.
Так как компания уже использует PHP для отображения своего онлайнового каталога, было бы логично использовать PHP и для создания Web-сервиса. PHP-библиотека NuSOAP позволяет легко и быстро разрабатывать Web-сервисы на PHP, поддерживает большую часть спецификации SOAP 1.1, а также может генерировать документы в соответствии со стандартом WSDL 1.1.
Теперь посмотрим, что нам нужно на стороне клиента. Мы хотим, чтобы работа с Web-сервисом была "достаточно простой". Вызовы Web-сервиса должны выполняться с локальной машины, без использования PHP-транслятора (или любого другого транслятора). Это можно реализовать с помощью простой HTML-страницы с некоторым количеством кода JavaScript. Хотя изначально наше приложение весьма минималистично, Dojo предоставляет возможности для расширения, позволяя подключать различную функциональность пользовательского интерфейса. Раз уж мы все равно используем Dojo, мы применим его возможности и для обработки XML.
Разворачиваем простой Web-сервис
Web-сервис, который мы напишем на PHP с помощью NuSOAP, возвращает список предлагаемых компанией рыболовных приманок заданного типа. В нашем простом примере имеется всего три типа приманок: trolling, casting и other.
В листинге 1 показано, насколько легко с помощью PHP и NuSOAP можно создать Web-сервис, работающий согласно спецификации SOAP.
Листинг 1. Простой Web-сервис, написанный на PHP
<?php
require_once('nusoap.php');
$server = new soap_server;
$server->register('retrieveByType');
function retrieveByType($type) {
if ($type == 'trolling') {
$arr[0] = 'Donzai Deep Swimmer 5 1/4 inch';
$arr[1] = 'Yosubi Squid-like 4 inch';
$arr[2] = 'Fortunata Imperial High Action';
} else if ($type == 'casting') {
$arr[0] = 'Silver Spring Mirrors Size 00';
$arr[1] = 'Gold Spring Mirrors Size 0';
$arr[2] = 'Mini Minnow Blue';
} else {
$arr[0] = 'None found!';
}
return $arr;
}
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>
|
В первой строке (содержащей инструкцию require_once), указывается необходимая для дальнейшей работы библиотека NuSOAP. Чтобы ее использовать, сначала нужно ее загрузить. Подробную информацию о загрузке NuSOAP можно найти по ссылке в разделе.
Далее мы создаем PHP-объект с именем $server. Это объект типа soap_server, определенного в PHP-библиотеке NuSOAP. Когда клиент вызывает одну из операций сервиса, этот объект используется для обработки операции и возвращения результата.
В следующей строке мы регистрируем функцию, которая будет доступна в качестве операции Web-сервиса. В данном случае у нас имеется только одна операция, и соответственно одна функция. В данном примере имена операции и функции совпадают (этого правила рекомендуется придерживаться во избежание путаницы). При вызове SOAP-операции retrieveByType будет вызвана PHP-функция с тем же именем.
Далее следует код вышеупомянутой PHP-функции. Обратите внимание, что эта функция принимает один параметр: type. Этот параметр проверяется на равенство одной из двух строк: trolling или casting. В случае совпадения операция возвращает набор приманок соответствующего типа, а в противном случае возвращается строка None found!.
В предпоследней строке показано, как Web-сервис обрабатывает вызовы операций. Как видно, Web-сервис ожидает, что операция будет вызвана с помощью POST-запроса. Это похоже на то, как в Web-приложениях обрабатываются данные, отправляемые формами. Также в этой строке содержимое запроса проверяется на равенство значению null, и в случае равенства оно конвертируется в пустую строку во избежание ошибок при дальнейшей обработке.
Наконец, вызывается метод service объекта server. Эта функция принимает в качестве параметра данные, отправленные в POST-запросе, а возвращает ответ, отправляемый клиенту.
Наш Web-сервис готов. Назовите этот файл webservice.php и поместите его на вашу любимую машину.
Вызываем сервис из кода JavaScript
Так как для обработки и разбора XML, возвращаемого нашим новым Web-сервисом, мы используем Dojo, в начале клиентского кода необходимо указать ссылку на библиотеку Dojo (как показано в листинге 2).
Листинг 2. Ссылаемся на библиотеку Dojo
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js" type="text/javascript"></script> |
Поместите этот код в элементе head HTML-страницы. Когда вы ссылаетесь на Dojo таким образом, вам не нужно загружать никаких библиотек, так как они уже доступны в Web. К сожалению, если Web-сайт, на который вы ссылаетесь, станет недоступен, ваше приложение перестанет работать. Но, к счастью, вряд ли это произойдет с Google.
В листинге 3 показано, как HTML-страница обращается к Web-сервису.
Листинг 3. Функция
invokeService()
function invokeService(type) {
soapMessage = '<?xml version="1.0" encoding="ISO-8859-1"?>';
soapMessage+='<SOAP-ENV:Envelope SOAP-ENV:";
soapMessage+=;encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"';
soapMessage+=' xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"';
soapMessage+=' xmlns:xsd="http://www.w3.org/2001/XMLSchema"';
soapMessage+=' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';
soapMessage+=' xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"';
soapMessage+=' xmlns:si="http://soapinterop.org/xsd">';
soapMessage+=' <SOAP-ENV:Body> <ns1:retrieveByType ';
soapMessage+='xmlns:ns1="http://fishinhole.com">';
soapMessage+=' <type xsi:type="xsd:string">' + type + '</type>';
soapMessage+=' </ns1:retrieveByType> </SOAP-ENV:Body> </SOAP-ENV:Envelope>';
if(window.XMLHttpRequest) {
httpRequest=new XMLHttpRequest();
} else if (window.ActiveXObject) {
httpRequest=new ActiveXObject("Microsoft.XMLHTTP");
}
httpRequest.open("POST",url,true);
if (httpRequest.overrideMimeType) {
httpRequest.overrideMimeType("text/xml");
}
httpRequest.onreadystatechange=populateDiv;
httpRequest.setRequestHeader("Man", url + " HTTP/1.1")
httpRequest.setRequestHeader("MessageType", "CALL");
httpRequest.setRequestHeader("Content-Type", "text/xml");
httpRequest.send(soapMessage);
valTimeout=setTimeout("timeout(httpRequest);",120000);
}
|
Хотя на первый взгляд может показаться, что кода здесь слишком много, содержимое этого листинга весьма понятно для разработчиков, знакомых с Ajax.
Сначала мы составляем сообщение согласно спецификации SOAP. Большая часть сообщения прописана непосредственно в коде. Исключение составляет тип приманки, который может иметь значение trolling, casting или other. Эти типы нам уже знакомы, за исключением other (который мы подставляем для проверки результата None found!).
После создания SOAP-сообщения мы добавляем несколько строк кода, чтобы гарантировать корректную работу в различных браузерах. Объект HTTP-запроса создается по-разному в зависимости от типа браузера, используемого клиентом. Этот объект называется httpRequest.
Как видно из вызова метода open объекта httpRequest, мы обращаемся к Web-сервису посредством POST-запроса. Этого следовало ожидать, исходя из предыдущего кода. Значение параметра url зависит от того, где вы будете разворачивать Web-сервис (формат адреса примерно таков: http://www.myhost.com/webservice.php).
Для функциональности страницы особую важность представляет вызов функции onreadystatechange объекта httpRequest. Мы задали для нее JavaScript-функцию populateDiv, она будет вызвана при получении ответа от Web-сервиса.
В следующих нескольких строках кода задаются заголовки сообщения. После этого вызывается метод send, осуществляющий «официальный» вызов операции Web-сервиса. Обратите внимание, что параметром этой функции является созданное ранее SOAP-сообщение.
В листинге 4 показана JavaScript-функция populateDiv.
Листинг 4. Функция
populateDiv
function populateDiv(){
try {
if(httpRequest.readyState==4) {
if(httpRequest.status==200) {
clearTimeout(valTimeout);
var text = httpRequest.responseText;
var dom = dojox.xml.parser.parse(text);
var docNode = dom.documentElement;
var html = "";
var returnElement = docNode.childNodes[0].childNodes[0].childNodes[0];
for (var i = 0; i < returnElement.childNodes.length; i++) {
html +="<br/>" +
dojox.xml.parser.textContent(returnElement.childNodes[i]);
}
var resultDiv=document.getElementById("resultDiv");
resultDiv.innerHTML = html;
}
}
} catch(e) {
alert("Error!"+e.description);
}
}
|
Обратите внимание, что в связи с тем, что здесь мы имеем дело как с механизмом запрос/ответ, так и с разбором XML, все тело функции заключено в блок try/catch. Мы отлавливаем все исключения и в целях отладки выводим их пользователю.
Здесь выполняется несколько проверок. Если ответ получен, объект запроса регистрирует состояние готовности номер 4. Если ответ корректен, объект запроса регистрирует статус 200.
При получении корректного ответа мы сбрасываем значение таймаута.
Далее мы получаем доступ к тексту ответа, который имеет формат XML и, возможно, удивительно напоминает ответ, который мы закодировали ранее. В нем будет текстовый элемент, указывающий тип приманки.
В следующей строке кода мы с помощью Dojo разбираем полученное SOAP-сообщение в формате XML и получаем доступ к корневому элементу документа.
Мы ищем в ответе от Web-сервиса один или несколько элементов item. Эти элементы находятся на четвертом уровне вложенности (что мы и указываем в строке, задающей значение объекта returnElement). Нам нужно получить доступ к потомкам корневого элемента четвертого уровня. Для получения этих элементов мы обходим всех потомков элемента-потомка третьего уровня (этот элемент называется return, что объясняет имя JavaScript-объекта).
Мы обходим данные элементы (потомков четвертого уровня), извлекаем из них текст (который в данном случае представляет собой описание приманки) и выводим перед этим текстом тэг <br/>, чтобы имя каждой новой приманки выводилось на отдельной строке.
И, наконец, мы получаем доступ к DIV-элементу, используемому для вывода ответа. Составленная HTML-разметка помещается в этот DIV-элемент и выводится на экран.
Мы написали код клиента и Web-сервиса, теперь давайте приступим к тестированию прототипа.
Вы можете запустить клиента на своей машине. Любой Web-браузер (например, Microsoft® Windows® Internet Explorer или Mozilla Firefox) может обработать расположенный на локальной машине HTML-файл, даже если в нем используется JavaScript-код.
На Web-странице вы увидите простое выпадающее меню, в котором можно выбрать тип приманки. Выберите в меню приманку Trolling, и под выпадающим меню вы увидите полученные от Web-сервиса результаты. Выберите приманку Casting и результаты поменяются. Если вы выберете Other, вы увидите текст None found!.
Совет директоров впечатлен вашей работой, вы уложились в отведенные сроки и создали "достаточно простой" Web-сервис.
Что еще более важно, вы продемонстрировали успешный вариант совместного применения простых в использовании технологий: PHP, NuSOAP и Dojo. Сделав это, вы проявили свою компетентность и показали, как можно быстро и эффективно интегрировать приложения. Наконец, в этом решении вам удалось скрыть все сложности реализации Web-сервиса.
Возможно, повышение не за горами!
| Описание | Имя | Размер | Метод загрузки |
|---|---|---|---|
| PHP-сценарий web-сервиса для этой статьи | webservice.php | 1КБ | HTTP |
| Код клиента HTML/JavaScript | client.html | 2КБ | HTTP |
Научиться
-
Use Dojo to process web service responses (developerWorks, июль 2010 г.): оригинал статьи. (EN)
- Познакомьтесь с отличным введением в
NuSOAP.(EN)
- Познакомьтесь с обучающим руководством по SOAP от w3schools.com. (EN)
- Следите за новостями в разделе технических событий и
Web-трансляций, в котором рассказывается о различных продуктах IBM и актуальных проблемах ИT-индустрии.(EN)
- Посетите бесплатный брифинг developerWorks Live!, чтобы быстро начать эффективную работу с продуктами и инструментами IBM, а также познакомиться с трендами ИT-индустрии. (EN)
- Следите за developerWorks в
Twitter.(EN)
Получить продукты и технологии
- Изучите набор инструментов Dojo.(EN)
- Загрузите библиотеку NuSOAP. (EN)
Обсудить
- Делитесь своими знаниями: присоединяйтесь к одной из наших групп developerWorks, посвященных Web-тематикам.
- В своем блоге Роланд Барсиа рассуждает о Web 2.0 и связующем ПО.
- Следите за совместными закладками членов developerWorks, посвященными Web-тематикам.
- Получите быстро ответы на свой вопросы: посетите форум приложений Web 2.0.
