Используем Dojo для обработки ответов от Web-сервисов

Упрощаем использование Web-сервисов с помощью Dojo

Web-сервисы позволяют организовать доступ к функциональности, не зависящий от языка и платформы. На стороне клиента набирает популярность Dojo – набор JavaScript-инструментов для создания богатых пользовательских интерфейсов с минимальными затратами усилий на программирование. Научитесь использовать Dojo для разбора и обработки ответов от Web-сервиса.

Брайан M. Кэри, консультант по информационным системам, Triangle Information Solutions

Photo of Brian CareyБрайан Кэри (Brian Carey) является консультантом по информационным системам, специализирующимся на Java, Java EE, PHP, Ajax и смежных технологиях. Микроблог Брайана доступен по адресу http://twitter.com/brianmcarey.



22.04.2011

Что такое Web-сервис?

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?

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.php1КБ
Код клиента HTML/JavaScriptclient.html2КБ

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Web-архитектура, Open source
ArticleID=650395
ArticleTitle=Используем Dojo для обработки ответов от Web-сервисов
publish-date=04222011