Использование Ajax для управления документами Lotus Notes

Немедленная реакция на действия пользователей вместо продолжительных перезагрузок используемых ими страниц легко реализуется при помощи технологии Ajax. Узнайте, как вид и агент помогают создавать Ajax-приложение, а также как определить API для организации взаимодействия сервера Domino и клиента.

Джоаким Дэйджерот, системный разработчик и технический руководитель, Strand Interconnect

Джоаким Дэйджерот (Joachim Dagerot) - системный разработчик и технический руководитель Strand Interconnect. Он участвует в международных интранет-сетях, обслуживающих более 130 миллионов пользователей. В настоящее время в основном занимается Web-разработкой, в частности, проблемами доступности и соответствия стандартам. В свое свободное время разрабатывает Web-сервисы и блоги на domino.dagerot.com. Связаться с ним можно по адресу jd@dagerot.com.



23.04.2007

Каждый из нас использовал систему поддержки списка текущих задач (To Do) того или иного типа. Такие системы обычно состоят из небольших фрагментов данных, которые должны быть пригодны для быстрого и легкого использования. Список To Do также является превосходным примером демонстрации работы технологии Asynchronous JavaScript and XML (Ajax) с Lotus Domino. В данной статье рассматривается, как можно использовать шаблон проектирования Ajax для создания приложения Lotus Notes под названием ToDo-list, предоставляющего пользователям немедленный ответ, и для обновления их задач.

В данной статье рассматривается процесс создания приложения ToDo-List. Предоставляется также возможность загрузить пример приложения, которое поможет в работе со статьей. Приложение использует Domino-агент для обработки Ajax-запросов, передаваемых из Web-браузера (таких как создание и обновление Notes-документов), и Domino-вид для генерирования XML, используемого в приложении. Данная статья предназначена для опытных разработчиков приложений Notes/Domino, знакомых с JavaScript и XML.

Ссылки на ознакомительные статьи по технологии Ajax приведены в разделе "Ресурсы" данной статьи.

Приложение ToDo-list работает со списком элементов To Do, каждый из которых содержит поля Subject и Status. Поле Subject хранит информацию о том, что это за элемент (см. рисунок 1); поле Status содержит либо 0 для невыполненного действия, либо 1 для завершенного действия.

Рисунок 1. Ajax-приложение ToDo-list
Рисунок 1. Ajax-приложение ToDo-list

Возможности Ajax-приложений

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

Предоставляемые Lotus Domino элементы проектирования делают разработку Ajax-решений на платформе Domino простой. Легко создать сессионный (для защиты и персонализации) Domino-агент, обрабатывающий Ajax-запросы. Кроме того, можно настроить Domino-вид на предоставление данных в форматах HTML, XML и даже JavaScript Serialized Object Notation (JSON). Есть все, что нужно для успешной реализации технологии Ajax.

Современные Web-браузеры и продуманная объектная модель документов (Document Object Model - DOM) как никогда облегчают создание полнофункциональных (rich) приложений для пользователей. Например, мы обычно включаем в наши проекты поля с опережением ввода данных, в которых пользователи получают предложения окончания ввода во время набора информации для облегчения поиска имен. Еще в одном проекте мы загружали страницу портала с маленькими блоками (то есть <DIV>). Каждый <DIV> заполняется информацией с сервера при Ajax-вызове. Некоторые блоки обновляются автоматически каждые 30 секунд, предоставляя менеджеру свежую информацию от ERP-системы (Enterprise Resource Planning).

Третий пример - это еще один портал, в котором заголовок каждого блока имеет маленькую пиктограмму "Add to my page". При нажатии пользователем этой пиктограммы серверу в фоновом режиме передается информация о том, на какой блок хочет подписаться пользователь. Сервер отвечает одним из двух сообщений: "The box is now on your personal page" (Блок теперь находится на вашей персональной странице) или "You have that box already!" (Вы уже подписаны на этот блок).

Во всех этих приложениях мы начинали разработку с создания спецификации API. Плохо специфицированный API может похоронить любой проект.


API

До начала кодирования приложения ToDo-list нужно решить, как форматировать информацию, передаваемую между клиентом и сервером. Разработчики системы могут выбрать любой желаемый формат обмена, но в настоящее время таким форматом обычно является XML, JSON или простой текст.

XML, JSON или простые аргументы

Для обмена данными между двумя компьютерами необходимо установить четко определенные правила, так чтобы отправитель и получатель знали, что делать с любой частью информации. Эти правила могут быть сложными, подробными, гибкими, либо простыми, краткими и легкими в адаптации.

Если выбранный формат является открытым, мы рекомендуем приоритет отдавать читабельности и целостности, а не малому размеру и малым накладным расходам. Вариантами (приведены в таблице 1) могут быть:

  • XML. XML-формат отлично подходит для структурированных и четко-определенных данных. При этом сервер и клиент хорошо знают, как будут выглядеть данные. Однако XML, возможно, излишне подробен, а XML-реализации в старых браузерах имеют свои особенности. К счастью, эти особенности на влияют на пример Ajax-приложения из данной статьи.
  • HTML. HTML-формат отлично подходит для передачи данных с сервера в Web-браузер для непосредственной визуализации, особенно в сравнении с XML, где клиент должен сначала преобразовать содержимое в HTML перед его визуализацией. HTML использовать не рекомендуется, если браузер должен проанализировать и прореагировать на данные.
  • JSON. JSON хорошо пригоден для чтения человеком и является маленьким по размеру (нет больших накладных расходов). JSON является родным для языка JavaScript, но требует дополнительного Java-кодирования на стороне сервера.
  • CSV. Comma-Separated Value (CSV), возможно, самый широко используемый и самый испытанный способ передачи данных между двумя системами. Некоторые утверждают, что он легко читается человеком, хотя мы не придерживаемся данной точки зрения. В этом формате нет ни контроля целостности, ни накладных расходов на это.
  • Text. Использование простого текста для обмена информацией подходит, например, в URL.

Таблица 1. Обзор различных форматов обмена данными

XMLJSONHTMLCSVText
Накладные расходыБольшиеСредниеБольшиеОчень маленькиеСредние
Проверка целостностиОчень хорошаяОчень простаяНетНетНет
ЧитабельностьХорошаяСредняяХорошаяНевозможноХорошая

В примерах данный статьи используется текстовый формат для запросов к серверу и XML для ответов. Необходимо также потратить некоторое время и усилия на определение XML. Это не так просто, как добавление дополнительного поля в чистой среде Lotus Notes.


Определение XML-формата

Использование встроенного генерирования XML в Lotus Domino

Можно использовать родной для Lotus Domino XML-формат --Domino XML (DXL)-- при запросе всего документа или элемента проекта. Одним из преимуществ такого подхода является то, что на стороне сервера писать кода нужно значительно меньше, а также можно использовать встроенный DXL-генератор.

Позднее в этой статье вы определите, какие методы клиент может послать на сервер. Но сейчас необходимо решить, какой диалект XML использовать для определения одного или нескольких элементов To Do. Каждый элемент To Do в приложении ToDo-list содержит три значения: ключ, тема и состояние. Ключ - это Universal ID (UID) документа Lotus Notes, хранящего ваш элемент To Do. Тема - это просто задание или действие, которое хочет выполнить пользователь. Состояние равно 0 для невыполненных заданий и 1 для завершенных заданий.

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

<response>
  <response status></response status>
  <document>
    <key></key>
    <subject></subject>
    <status></status>
  </document>
  <document>
    <key></key>
    <subject></subject>
    <status></status>
  </document>
</response>

Теперь, когда установлены API, формат обмена и XML-стандарт, можно начинать разработку серверных функций. После этого можно перейти к кодированию на стороне клиента. Однако сначала нужно решить, какие действия сервер будет выполнять с вашими документами.


Создание вызова клиент-сервер

Каждый вызов, генерируемый клиентом, должен содержать аргумент action, для того чтобы сервер знал, что делать. Иногда необходимо также передать дополнительные аргументы, например, если нужно переключать состояние элемента. В этом случае выполняется действие ToggleStatus, а дополнительный аргумент должен содержать информацию о том, какой документ меняет состояние, для того чтобы сервер Domino мог выполнить нужное действие с нужным документом.

Все вызовы от клиента выполняются при помощи метода HTTP GET с несколькими URL-аргументами. Ниже приведен пример полного URL, включающего в себя названия аргументов method и key.

http://host/ibm/ajaxdemo.nsf/AjaxHandler?open&method=deleteDocument&key=88877766fefe5678

Какое действие должен обрабатывать сервер?

Web-страница может использовать много различных методов в вашем API, например, createDocument, updateDocument, deleteDocument, getDocument и toggleStatus. Каждый метод принимает один или несколько аргументов. Все действия по созданию, обновлению, удалению документа и изменению его состояния меняют информацию в базе данных, и это изменение должно быть отражено в списке элементов To Do на Web-странице. Один из способов отобразить это изменение - позволить клиенту посылать дополнительный запрос для получения списка элементов каждый раз, когда производится изменение базы данных. Лучшим решением является настройка агента на возврат обновленного списка To Do при каждом вызове агента (более подробно об этом рассказывается позже).

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

Таблица 2. Определенные действия

МетодНазначениеАргументыВозвращаемое значение
CreateDocumentСоздает новый документ Lotus Notes и заполняет его поля предоставляемыми даннымиСписок полей; каждый аргумент содержит имя поля, тип и значениеXML-объект, содержащий все элементы
UpdateDocumentЗапрашивает обновление, предоставляя идентификатор документа, имя поля и изменяемое значениеУникальный ID документа и аргумент field; аргумент field содержит имя поля и новое значение поляXML-объект, содержащий все элементы
DeleteDocumentУдаляет документУникальный ID удаляемого документаXML-объект, содержащий все элементы
GetDocumentВозвращает содержимое документаУникальный ID извлекаемого документаXML-объект, содержащий запрошенный элемент
ToggleStatusПереключает состояние указанного элемента To DoУникальный ID документа, состояние которого изменяетсяXML-объект, содержащий все элементы

Эти пять действий – все, что вам нужно для создания полного API между сервером Domino и Web-браузером. Теперь перейдем к коду агента, работающего на стороне сервера.


Сторона сервера

Сервер Domino гарантирует должную обработку всех Ajax-запросов. На вызовы, управляющие данными, должен отвечать какой-то интеллектуальный механизм на стороне сервера - в данном примере агент. Вызовы, которые просто запрашивают информацию, могли бы легко положиться на виды Lotus Notes, которые являются отличным источником XML.

Вид для перечней

В данном примере мы используем вид Lotus Notes, настроенный на отображение XML. Чтобы избежать добавления сервером Lotus Domino своего собственного HTML-кода, вид настраивается на представление своего содержимого в формате HTML.

В приложении ToDo-List нужен только один столбец в этом виде для генерирования полного XML-узла для каждого элемента To Do в системе. Первый столбец скрыт и используется только для установки правила сортировки (см. рисунок 2).

Рисунок 2. Lotus Domino Designer показывающий XML-вид
Рисунок 2. Lotus Domino Designer показывающий XML-dbl

Кроме этого вида нам нужна форма $$viewtemplate, соотносящаяся с видом. Эта форма содержит окружающий XML-код (рисунок 3).

Рисунок 3. Часть формы $$viewtemplate
Рисунок 3. Часть формы $$viewtemplate

Представление существующей информации является важной функцией, и показанное на рисунке 3 решение идеально подходит под наши требования. Теперь необходимо создать агент Lotus Notes, который будет отвечать на запросы.

Domino-агент для команд к серверу

Рекомендации W3C

Помните, что консорциум W3C (World Wide Web Consortium) рекомендует использовать метод POST при изменении данных на сервере и метод GET для всех запросов, не меняющих информацию на сервере.

Вы знаете, как получить данные с сервера Domino способом, соответствующим шаблону Ajax. Так как же можно использовать Domino-агент для получения Ajax-вызовов?

Во-первых, необходимо определить, должен ли агент вызываться методом HTTP GET или методом POST. Поскольку элемент To Do содержит так мало информации, вы можете использовать метод GET. Это означает, что все аргументы для сервера передаются в строке URL следующим образом:

/database.nsf/ajaxHandlerAgent?openagent&method=UpdateDocument&key=FFF&status=0

Агент анализирует аргументы в строке URL и поступает в зависимости от значения аргумента method. Следующий листинг показывает, как ajaxHandlerAgent выполняет необходимые действия на основе аргумента method.

UrlArguments args = new UrlArguments(); (1)
args.fromSession(session);

String method = args.getString("method"); if("ToggleStatus".equals(method)) { try { Document doc = thisDB.getDocumentByUNID(args.getString("key")); (2) String newStatus="1"; if(doc.hasItem("status")) { String currStatus = doc.getItemValueString("status"); if("1".equals(currStatus)) { newStatus=="0";} } doc.replaceItemValue("status",newStatus); pw.println("[" + "/" + thisDB.getFilePath() + "/XmlView?open]"); doc.save(true,false); } catch(Exception e) { pw.println(e);(3) } }

Примечание: Приведенный здесь фрагмент кода агента показывает только действие ToggleStatus. Полный код этого агента, а также код клиента, доступен в разделе "Загрузка".

Обратите особое внимание на следующие строки в данном листинге: (1): Класс UrlArguments - это маленький вспомогательный класс, разбирающий URL-аргументы в объект hashtable. (2): В этой строке аргумент universalID каждого документа Lotus Notes вступает в работу. (3): Обработка ошибок в этой строке недостаточна для рабочей среды и должна быть переработана.

Видите ли вы перенаправление, которое агент выполняет для передачи данных обратно в вид на клиент?

Разрешите Domino-агенту обслуживать вид

Огромным преимуществом использования Ajax является способность предоставить пользователям мгновенную, актуальную информацию с сервера. То есть, в приложении ToDo-list вы передаете назад клиенту свежий список элементов в качестве ответа на все запросы к серверу. Это осуществляется при помощи разрешения агенту выполнять серверное перенаправление к XML-виду, как показано в следующей строке кода. Web-браузер затем использует содержимое XML-вида как ответ на все запросы к агенту.

pw.println("[" + "/" + thisDB.getFilePath() + "/XmlView?open]");


Сторона клиента

В браузере необходимы: функция для создания Ajax-запроса, места-заполнители для ответной информации и одна или более активных точек, с которыми может взаимодействовать пользователь. Точками взаимодействия может быть любой объект, способный активировать событие. Наиболее широко известными типами являются кнопки input и анкеры (anchor) (см. рисунок 4). Если пользователи знакомы с категоризированными видами, вы знаете, как может выглядеть точка взаимодействия. Ajax делает эту реализацию еще лучше: загружая только одну категорию при развертывании пользователем вида, можно сэкономить много времени и ресурсов, а также предоставить пользователям дополнительные удобства.

Рисунок 4. Точки взаимодействия в приложении ToDo-list
Рисунок 4. Точки взаимодействия в приложении ToDo-list

На рисунке 4 все доступные активные точки выделены розовым цветом. HTML-код для различных активных точек отличается. Ссылки REFRESH! и Create new todo! являются статическим кодом, тогда как ссылка для символа состояния (красный X и зеленая галочка) и тема элемента должны визуализироваться на лету. В данном приложении настраивается вспомогательная функция, и эта процедура полагается на пиктограммы, предоставляемые сервером Domino. Независимо от того, какой HTML и JavaScript-код необходим для генерирования визуального ответа пользователю, запрос к серверу формируется одинаково с использованием объекта XMLHttpRequest.

Формирование и обработка Ajax-запроса

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

var xmlHttp;
function createXMLHttpRequest() { 
  if (window.ActiveXObject) { 
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); 
  }
  else if (window.XMLHttpRequest) { 
    xmlHttp = new XMLHttpRequest(); 
  }
}

Создание, передача и извлечение

Для читабельности легче отобразить каждый метод API в один метод на стороне клиента и метод с таким же названием на стороне сервера. JavaScript-функция, показанная в следующем листинге, вызывается каждый раз, когда пользователь нажимает на пиктограмму состояния (зеленая галочка или красный X). Он начинается с объявления функции (02), выполняющейся каждый раз, когда объект xmlHttp получает изменение состояния (12).

В строке (10) заполняется глобальная переменная Http, а строка (11) создает аргументы, добавляемые в URL. В строке (13) инициируется Ajax-объект для передачи в строке (16).

01  function toggleStatus(key) {
02    this.handleStateChange = function() {
03      if(xmlHttp.readyState == 4) {
04        if(xmlHttp.status == 200) {
05          refreshTodoList(xmlHttp.responseXML);
06        }
07      }
08    }
09
10  createXMLHttpRequest(); // создать строку обновления
11    var args='&method=ToggleStatus&key=' + key;
12    xmlHttp.onreadystatechange = this.handleStateChange;
13    xmlHttp.open("GET"
14      ,"./HandleAjaxRequests?open" + args
15      ,true);
16    SMLHTTP.send(null);
17  }

Есть две проверки перед дальнейшей передачей ответа в XML-анализатор в строке (05).


Решение для кросс-серверных реализаций

Все современные реализации объекта XMLHttpRequest (известного также как XHR) имеют ограничение системы защиты (запрещающей обрабатывать запрос различными доменами), затрудняющее использование Ajax-решения на нескольких серверах. Мы не будем углубляться в то, как преодолеть это ограничение, а также в то, можете вы это сделать или нет. Вместо этого приведем некоторые альтернативные решения, которые могут потребовать дополнительного кодирования, но (как минимум) предоставляющие пользователям такую же функциональность, как и реализация XMLHttpRequest:

  • Подход iframe был традиционным способом получения Ajax-функциональности до повсеместного распространения объекта XMLHttpRequest. Загружая содержимое в скрытый объект iframe и обрабатывая его в фоновом режиме, вы можете иметь более или менее аналогичную XHR-решению функциональность.
  • Подход с использованием прокси является сегодня наилучшим и, возможно, самым типичным решением в случаях, когда XHR вызывает не исходный сервер. В этом подходе вы должны иметь прокси на сервере, обслуживающем Ajax-страницы. Прокси получает все Ajax-вызовы и направляет их в соответствующие назначения.
  • Шаблон проектирования с прокси имеет также возможности для добавления кэширования и проверки корректности содержимого, обеспечивая хорошее решение даже тогда, когда все содержимое загружается с одного и того же сервера.

Резюме

Шаблон проектирования Ajax является хорошим решением для пользователей, поскольку они получают немедленную реакцию на каждое выполненное ими действие. Он также хорош для сохранения целостности данных на стороне сервера при ошибках взаимодействия и тому подобное. Однако есть несколько моментов, которые Domino-разработчики должны учитывать перед развертыванием Ajax-решений.

Во-первых, объект XMLHttpRequest не является стандартом даже при наличии проекта консорциума W3C по созданию такого стандарта. Еще одна проблема, о которой стоит задуматься, - это производительность сервера. Ajax-решение может не увеличивать требования к пропускной способности, но оно будет нагружать сервер Domino в плане увеличения количества транзакций. В третьих, вы, возможно, захотите избежать создания решений, не поддерживающих функциональность кнопки Back Web-браузеров.

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


Загрузка

ОписаниеИмяРазмер
Пример приложения ToDo-list, управляемого AJAXAjaxDemo_part1.nsf384 KB

Ресурсы

Научиться

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

Обсудить

Комментарии

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=Lotus
ArticleID=211475
ArticleTitle=Использование Ajax для управления документами Lotus Notes
publish-date=04232007