четверг, 22 апреля 2010 г.

Работа с веб-сервисом в Pocket Internet Explorer

Так уж вышло, что я работаю над мобильным клиентом под Pocket IE. И это единственное, что может быть хуже чем просто IE. Но раз уж так вышло, сейчас я покажу как используя javascript и много терпения работать с веб-сервисом прямо из html кода. Поехали!


Итак, для начала нам нужно создать экземляр XMLHttpRequest. Напомню, что XMLHttpRequest позволяет осуществлять HTTP-запросы к удаленному серверу без необходимости перезагружать страницу. Важно, что XMLHTTP работает только с файлами, находящимися на том же домене, что и использующая XMLHTTP страница. Как и в случае JavaScript, это сделано в целях безопасности.
Кроме пересылки XML, через XMLHTTP можно обмениваться данными формы и просто текстовыми строками.
Метод приведенный ниже работает под все браузеры:

function getXMLHttpRequest() {
var xmlHttp;
try {
// Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
}
catch (e) {
try {
// Internet Explorer
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
alert("This browser doesn`t support web service!");
}
}
}
return xmlHttp;
}


Теперь можно переходить к функции обработчика запроса, которая в общих чертах выглядит так:

xmlHttp.onreadystatechange = function(){
if (xmlHttp.readyState == 4) {
//код обработки
}
};


Немного о том, что такое xmlHttp.readyState.
Запрос xmlhttp регулярно отчитывается о своем состоянии через вызов функции xmlhttp.onreadystatechange. Состояние под номером 4 означает конец выполнения, поэтому функция-обработчик при каждом вызове проверяет - не настало ли это состояние.

Вообще, список состояний readyState такой:


  • 0 - Unitialized
  • 1 - Loading
  • 2 - Loaded
  • 3 - Interactive
  • 4 - Complete
Состояния 0-2 вообще не используются.

Вызов функции с состоянием Interactive в теории должен происходить каждый раз при получении очередной порции данных от сервера. Это могло бы быть удобным для обработки ответа по частям, но Internet Explorer не дает доступа к уже полученной части ответа.
Firefox дает такой доступ, но для обработки запроса по частям состояние Interactive все равно неудобно из-за сложностей обнаружения ошибок соединения. Поэтому Interactive тоже не используется.

На практике используется только последнее, Complete. Про readyState и баги, связанные с ним можно прочитать тут.

Но вернемся обработке результата.
Пара слов о веб-сервисе. Веб-сервис поднят на JBoss с помощью java-аннотаций @Webservice и иже с ним. Так что специфику возвращаемого результата приходится учитывать при обработке. Например, в конце возвращаемой xml неожиданно стал возникать тэг < br /> Отловить причину пока не удалось.

Теперь о самом возвращаемом результате. Посмотреть его можно с помощью вызова xmlHttp.responseText. Далее эту строку мы преобразуем в xml документ:

function getXmlDoc(text) {
var xmlDocument = new ActiveXObject("Microsoft.XMLDOM");
xmlDocument.async = "false";
xmlDocument.loadXML(text);
return xmlDocument;
}

Опять же по непонятным причинам, xmlHttp.responseXML возвращается пустой, видимо, формат не распознается.

Для того, чтобы в данном документе найти значение нужного нода, пишем еще один метод:

function getTagValue(xmlDocument, tagName) {
return xmlDocument.getElementsByTagName(tagName)[0].childNodes[0].nodeValue;
}

где tagName имя элемента.
В итоге можно получить нечто следующее:

xmlHttp.onreadystatechange = function(){
if (xmlHttp.readyState == 4) {
var text = xmlHttp.responseText;
var xmlDocument = getXmlDoc(text);
var successful = getTagValue(xmlDocument, "successful");
if (successful == "true") {
alert("request was successful!");
} else {
alert("request was unsuccessful!");
}
}
};

И теперь нам остается только отправить этот запрос:

xmlHttp.open("GET", url, false);
xmlHttp.send("");


Надеюсь, данный пост поможет вам!

Related Posts by Categories



Комментариев нет:

Отправить комментарий