Web-сервисы Java, Часть 2: Погружение в Axis2: AXIOM

Объектная модель документов AXIOM - фундамент Web-сервисов Apache Axis2

В основе инфраструктуры Web-сервисов Apache Axis2 лежит новая модель XML документов AXIOM, обеспечивающая эффективную обработку сообщений SOAP. В отличие от традиционных моделей документов AXIOM создает поисковый образ документа в памяти только при обращении к нему. Узнайте, почему эта конструкция "по-запросу" является огромным шагом навстречу эффективной обработке SOAP и какое место при этом отводится приложениям XOP/MTOM, привязке данных и рабочим характерисикам.

Денис Сосноски, консультант, Sosnoski Software Solutions, Inc.

Денис Сосноски (Dennis Sosnoski) - основатель и ведущий специалист консалтинговой компании по технологиям Java - Sosnoski Software Solutions, Inc., специализирующейся в обучении и консультировании по проблемам XML и Web-сервисов. Он имеет более чем 30-летний опыт работы в профессиональном проектировании ПО, специализируясь на серверных XML и Java-технологиях. Денис является основным разработчиком интегрированной системы с открытым программным кодом JiBX XML Data Binding, построенной на базе технологии классов Java и связанной системы Web-сервисов JibxSoap, также как и системы Web-сервисов Apache Axis2. Он также был одним их экспертов при разработке спецификаций JAX-WS 2.0.



17.04.2007

Еще одна документная модель?

Выпуск Apache Axis2 1.1 сулил множество замечательных возможностей приверженцам инфраструктрур Web-сервисов серии Apache. Мы рассмотрим сам Axis2 в одной из следующих публикаций, но в данной статье мы попытались проникнуть внутрь Объектной Модели AXIs (AXIOM) - модели XML документа, лежащей в основе Axis2. AXIOM - одна из основных инноваций в Axis2, и одна из причин того, что Axis2 показывает гораздо лучшие рабочие характеристики, чем оригинальный Axis. Данная статья познакомит вас с тем, как работает AXIOM, как AXIOM складывается из разных частей Axis2, и, наконец, как рабочие характеристики AXIOM соотносятся с рабочими характеристиками других объектных моделей документов Java™.

Документные модели - обычный подход к обработке XML. Для разработки Java доступны многие их виды, в том числе разные реализации исходной спецификации W3C DOM, JDOM, dom4j, XOM, и другие. Каждая модель претендует на наличие каких-то преимуществ по сравнению с другими, будь то рабочие характеристики, функциональная гибкость или строго соблюдаемое соответствие стандарту XML, и каждая имеет преданных сторонников. Итак, зачем Axis2 потребовалась новая модель? Для ответа на этот вопрос нужно знать, как структурированы сообщения SOAP, и, в особенности, как добавляются расширения к базовой инфраструктуре SOAP.

Обнаружение SOAP

Сам SOAP это просто тонкая оболочка, обертка, в которую заключена полезная XML информация приложения. В Листинге 1 приведен пример программы, где все элементы SOAP имеют префикс soapenv. Основную часть документа составляют данные приложения, являющиеся содержимым элемента soapenv:Body.

Листинг 1. Образец SOAP
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header/>
  <soapenv:Body>
    <matchQuakes xmlns="http://seismic.sosnoski.com/types">
      <min-date>2001-01-06T11:10:43.446Z</min-date>
      <max-date>2001-10-24T19:49:13.812Z</max-date>
      <min-long>-150.94307</min-long>
      <max-long>-22.594208</max-long>
      <min-lat>-11.44651</min-lat>
      <max-lat>55.089058</max-lat>
    </matchQuakes>
  </soapenv:Body>
</soapenv:Envelope>

Несмотря на простоту базовой оболочки SOAP, она делает возможной неограниченное добавление расширений посредством использования необязательного компонента header (заголовок). Заголовок обеспечивает место для добавления метаданных любого типа, которые сопутствуют данным приложения, будучи невидимыми ему (Вы можете включать данные приложения в заголовок, хотя нет убедительной причины, по которой вы бы предпочли сделать это вместо того, чтобы использовать компонент body (тело) для данных приложения). Расширения, добавляемые к SOAP (такие, как все семейство расширений WS-*) могут использовать заголовок для своих собственных целей, не влияя на приложение. Это позволяет расширениям действовать как самостоятельные дополнительные приложения, где конкретные функции расширения необходимые приложению могут быть выбраны во время ввода в действие, а не включены непосредственно в программный код.

В Листинге 2 показаны те же данные приложения, что и в Листинге 1, но с добавлением информации об адресации WS-Addressing. В то время, как исходное сообщение SOAP можно было бы, вероятно, передать лишь посредством транспортного протокола HTTP (поскольку HTTP обеспечивает двустороннее соединение для немедленной передачи ответа клиенту), приведенная в Листинге 2 версия может быть обработана и другими протоколами, поскольку имеет метаданные ответа, непосредственно включенные в SOAP сообщение с запросом. Было бы даже проще включить этап промежуточной буферизации передаваемых данных при обработке сообщения в Листинге 2, поскольку метаданные содержат информацию о координатах места, куда посылается запрос, и места, куда должен быть доставлен ответ.

Листинг 2. Образец SOAP с WS-адресацией
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:wsa="http://www.w3.org/2005/08/addressing">
  <soapenv:Header>
    <wsa:To>http://localhost:8800/axis2/services/SeisAxis2XBean</wsa:To>
    <wsa:ReplyTo>
      <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
    </wsa:ReplyTo>
    <wsa:MessageID>urn:uuid:97AE2B17231A8584D811537402403691</wsa:MessageID>
  </soapenv:Header>
  <soapenv:Body>
    <matchQuakes xmlns="http://seismic.sosnoski.com/types">
      <min-date>2000-03-28T13:13:08.953Z</min-date>
      <max-date>2001-03-11T02:26:54.283Z</max-date>
      <min-long>-81.532234</min-long>
      <max-long>65.25895</max-long>
      <min-lat>-14.234512</min-lat>
      <max-lat>57.174187</max-lat>
    </matchQuakes>
  </soapenv:Body>
</soapenv:Envelope>

Дилемма документной модели

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

Но документные модели - не слишком эффективный способ работы с XML, который используется для обмена данными между приложениями. Данные приложения обычно имеют предопределенную структуру, и большинство разработчиков предпочитают работать с ними в виде объектов данных, а не строк XML. Конвертирование данных из объектов данных в XML и наоборот составляет вид работы, который называется привязкой данных. Привязка данных не только более удобна для разработчиков, чем работа с документной моделью, она более эффективна и в том, что касается рабочих характеристик приложения и использования памяти.

Поэтому большинство приложений стремятся использовать привязку данных при работе с данными приложения сообщения SOAP, но документная модель более удобна при работе с метаданными, находящимися в заголовке. Идеальный подход должен комбинировать обе техники в рамках одной среды SOAP, но обычные документные модели не позволяют сделать это. Они предназначены для работы со всем документом или, по меньшей мере, со всем поддеревом документа. Они не предназначены для работы с отдельными частями документа, что идеально подходит SOAP.

Построение дерева AXIOM

Кроме AXIOM, есть и другое отличие Axis от Axis2. В отличие от исходного Axis, использующего стандартный парсер (SAX) помещения в стек для обработки XML, Axis2 использует парсер (StAX) выталкивания из стека. При первом подходе, анализатор контролирует обработку - вы передаете анализатору документ для обработки и ссылку на заголовок. Затем он использует заголовок для возвратного обращения к коду при обработке документа. Код заголовка может использовать информацию, передаваемую обратными вызовами, но не может воздействовать на обработку (кроме случаев генерации исключительной ситуации и выводе сообщения об ошибке). При втором подходе анализатор фактически является итератором для прохождения всех компонентов документа по требованию.

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

AXIOM построен на основе интерфейса StAX анализатора выталкивания из стека. AXIOM обеспечивает виртуальную модель документа и расширяет ее по требованию, выстраивая ровно такую древовидную структуру модели представления документа, какая запрашивается клиентским приложением. Эта виртуальная модель документа работает на уровне элементов в XML документе. Представление элемента создается, когда анализатор сообщает открывающий тег элемента, но внутренняя форма этого элемента по сути дела лишь оболочка, содержащая ссылку на анализатор. Если приложению необходимо получить данные о содержании элемента, оно просто запрашивает нужную информацию, вызывая метод интерфейса (такой как метод org.apache.axiom.om.OMContainer.getChildren()). Элемент затем выстраивает дочернее содержимое из анализатора в ответ на вызов метода.

Поскольку парсер доставляет данные в порядке их расположения в документе (в том же порядке, в котором они идут в тексте XML документа), реализуемая AXIOM конструкция "по требованию" нуждается в грамотном управлении. Например, нет ничего необычного в том, чтобы иметь несколько элементов в незавершенном состоянии (в стадии конструирования), но эти элементы все должны располагаться по линии наследования. В виде стандартной древовидной диаграммы XML с корневым элементом вверху, незаконченные элементы всегда будут находиться на направленной вниз линии в правой части дерева. Чем больше данных запрашивается приложением, тем дальше дерево разрастается вправо; с выполнением элементов снизу вверх.


Работа с AXIOM

Все модели XML документов имеют много общего в том, что касается их API (что не удивительно, поскольку все они работают с одними и теми же данными, служащими основой для расширения), но каждая имеет свои особенности, отличающие ее от остальных. Оригинальная Объектная Модель Документа W3C (W3C DOM) проектировалась так, чтобы обеспечивать межязыковую и межплатформную совместимость, поэтому она использует интерфейсы и избегает использовать коллекции, пригодные лишь для Java, в пользу собственных версий. JDOM использует конкретные классы вместо интерфейсов и объединяет стандартные классы коллекций Java для API, которые многие разработчики в Java считают более дружественными, чем DOM. dom4j объединяет сходные с DOM интерфейсы с классами коллекций Java для создания очень гибкого API, обеспечивающего массу возможностей - за счет некоторой сложности.

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

AXIOM в действии

API модели AXIOM, пожалуй, ближе всего к DOM по общим свойствам, но имеет собственные характерные черты. Например, методы доступа построены скорее на основе java.util.Iterator экземпляров класса для доступа к компонентам (возвращаемые методом org.apache.axiom.om.OMContainer.getChildren() и подобными ему), чем списка любого вида. Вместо индексации компонентов в списке навигатор использует методы org.apache.axiom.om.OMNode.getNextOMSibling() и org.apache.axiom.om.OMNode.getPreviousOMSibling() для последовательного продвижения по узлам на уровне дерева документа (сходные с DOM в этом случае). Такое структурирование методов доступа и навигации отвечает работе по построению дерева по требованию, поскольку это значит, что AXIOM может позволить вам перейти к первому дочернему элементы вашего стартового элемента без необходимости сперва обработать все дочерние элементы.

Как и DOM и dom4j, AXIOM определяет API, используемый для доступа и управления представлением дерева посредством интерфейсов. Дистрибутив AXIOM имеет несколько разных специализированных реализаций этих интерфейсов. Одна из реализаций (в пакете org.apache.axiom.om.impl.dom) с двойной головкой поддерживает как AXIOM, так и DOM интерфейсы в теми же эксплуатационными классами. Это может быть полезно из-за количества расширений Web-сервисов, предназначенных для работы с взглядом DOM на данные. Для более общего использования пакет org.apache.axiom.om.impl.llom предоставляет реализацию, основанную на связанных списках объектов. ("ll" - часть имени пакета). Существуют также расширения обоих базовых интерфейсов org.apache.axiom.om и их реализации в пакете org.apache.axiom.soap, предназначенные для использования с сообщениями SOAP.

Чтобы увидеть API модели AXIOM в действии, рассмотрим фрагменты кода программы, написанной для оценки рабочих характеристик AXIOM по сравнению с другими документными моделями. В Листинге 3 приведен первый пример, основанный на коде, используемом для построения представления AXIOM входного документа. Как и для DOM и dom4j, прежде чем сделать что-либо в AXIOM, вам необходим мастер для постройки компонентных объектов модели. Код в Листинге 3 выбирает основные реализации интерфейсов AXIOM из связанного списка, используя реализацию org.apache.axiom.om.impl.llom.factory.OMLinkedListImplFactory интерфейса org.apache.axiom.org.OMFactory. Интерфейс мастера включает в себя методы для построения документа напрямую из различных ресурсов, а также методы создания отдельных компонентов представления XML документа. В Листинге 3 использован метод построения документа из входного потока. Объект, возвращаемый методом build(), фактически является экземпляром org.apache.axiom.om.OMDocument, хотя это и не определено данным кодом.

Листинг 3. Размер документа в AXIOM
import org.apache.axiom.om.*;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.impl.llom.factory.OMLinkedListImplFactory;
    ...
    private XMLInputFactory m_parserFactory = XMLInputFactory.newInstance();
    private OMFactory m_factory = new OMLinkedListImplFactory();
    ...
    protected Object build(InputStream in) {
        Object doc = null;
        try {
            XMLStreamReader reader = m_parserFactory.createXMLStreamReader(in);
            StAXOMBuilder builder = new StAXOMBuilder(m_axiomFactory, reader);
            doc = builder.getDocument();
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
            System.exit(0);
        }
        return doc;
    }

В Листинге 3 использован класс org.apache.axiom.om.impl.builder.StAXOMBuilder для построения представления документа разделением входного потока. Так создается экземпляр парсера StAX и базовая структура документа до возврата, оставляя парсер внутри корневого элемента документа; остальная часть представления документа будет создана позже при необходимости. AXIOM не должен обязательно строиться с использованием парсера StAX. В действительности, org.apache.axiom.om.impl.builder.SAXOMBuilder это частичная реализация конструктора на основе парсера SAX с помещением в стек. Но если вы встроите модель любым другим способом, то теряете преимущества конструкции по требованию.

В Листинге 4 приведен код, используемый для "прохождения" через элементы в представлении документа и накапливающий общую информацию (счетчик элементов, счетчик и общая длина значения атрибута текста и счетчик и общая длина содержания текста). Метод walk() в нижней части получает документ для подведения результатов, вместе с суммированной структурой данных, в то время как метод walkElement() в верхней части обрабатывает один элемент (вызывает себя рекурсивно для обработки дочерних элементов).

Листинг 4. Навигация в AXIOM
    /**
     * Двигаясь по дереву, дойдите до элемента. При этом вы будете рекурсивно обходить
     * узлы документы ниже элемента, собирая итоговую информацию.
     *
     * элемент @param - элемент, который надо пройти
     * итоговая информация @param - итоговая информация документа
     */
    protected void walkElement(OMElement element, DocumentSummary summary) {

        // включаем значения атрибутов в итоговую  информацию
        for (Iterator iter = element.getAllAttributes(); iter.hasNext();) {
            OMAttribute attr = (OMAttribute)iter.next();
            summary.addAttribute(attr.getAttributeValue().length());
        }

        // перебераем дочерние элементы
        for (Iterator iter = element.getChildren(); iter.hasNext();) {

            // обрабатываем дочерний элемент в зависимости от типа
            OMNode child = (OMNode)iter.next();
            int type = child.getType();
            if (type == OMNode.TEXT_NODE) {
                summary.addContent(((OMText)child).getText().length());
            } else if (type == OMNode.ELEMENT_NODE) {
                summary.addElements(1);
                walkElement((OMElement)child, summary);
            }
        }
    }

    /**
     * Проходим и суммируем документ. Этот метод проходит через узлы,
     * собирая итоговую информацию.
     *
     * @param doc - представление документа, который надо пройти
     * @param summary - итоговая информация документа
     */
    protected void walk(Object doc, DocumentSummary summary) {
        summary.addElements(1);
        walkElement(((OMDocument)doc).getOMDocumentElement(), summary);
    }

Наконец, в Листинге 5 приведен программный код, используемый для записи представления документа в выходной поток. AXIOM определяет несколько методов вывода как часть интерфейса OMNode, включая варианты вывода (как выходной поток, обычная запись символов, запись потока StAX), вывод с форматированием информации или без него, с возможностью доступа к представлению документа после записи или без (что требует построения полного представления, если оно не было построено полностью). Интерфейс OMElement определяет другие способы доступа к информации документа через получение парсера StAX от элемента. Эта способность получать XML из представления, используя парсер, предлагает привлекательную для разработчика симметрию и хорошо работает, когда представление AXIOM создается по требованию (поскольку парсер, используемый для построения представления, может затем быть возвращен напрямую).

Листинг 5. Запись документа из AXIOM
    /**
     * Выводим документ как XML-текст.
     *
     * @param doc - представление документа, которое должно выводиться
     * @param out - выходной поток XML-документа
     */
    protected void output(Object doc, OutputStream out) {
        try {
            ((OMDocument)doc).serializeAndConsume(out);
        } catch (Exception ex) {
            ex.printStackTrace(System.err);
            System.exit(0);
        }
    }

AXIOM предоставляет базовые мотоды для изменения компонентов существующего документа (такие, как метод OMElement.setText(), переводящий содержимое элемента в текст). Если вы начинаете с нуля, вам нужно будет создать новые экземпляры компонентов напрямую. Поскольку AXIOM API основан на интерфейсах, он использует мастер для создания текущих реализаций компонентов.

Более подробно об AXIOM API см. ссылки на учебники по AXIOM и JavaDocs в разделе Ресурсы.

MTOM в AXIOM

Одним из наиболее интересных свойств AXIOM является его встроенная поддержка стандартов W3C XOP и MTOM, используемых в последних версиях приложений SOAP. Эти два стандарта работают вместе, посредством оптимизированной двоичной компоновки XML - XML-binary Optimized Packaging (XOP) обеспечивается логическое включение в XML любых двоичных данных; механизм оптимизации передачи сообщений MTOM (SOAP Message Transmission Optimization Mechanism) применяет технику XOP к сообщениям SOAP. XOP и MTOM являются принципиальными характеристиками нового поколения инфраструктур Web-серверов, поскольку они наконец обеспечивают поддержку интероперабельных приложений и тем самым устраняют текущие проблемы в данной области.

XOP работает с данными, представленными в системе кодировки символов с основанием 64. Base64 кодировка преобразует любые значения данных в ASCII символы, пригодные для печати, используя один символ ASCII для представления каждых 6 битов информации исходных данных. Поскольку двоичные данные не могут быть размещены в XML (XML работает только с символами, а не непосредственно с байтами; даже использование номера кода символа недопустимо в XML), кодировка base64 незаменима для размещения двоичных данных в сообщениях XML.

XOP заменяет существующий в кодировке base64 текст специальным элементом включения "Include" из области имен XOP. Элемент включения предоставляет URI, который определяет отдельную сущность (вне документа XML), которая есть существующие данных, которые должны быть включены в документ XML. как правило, этот URI будет идентифицировать каждый отдельный блок внутри одной и той же передачи как документ XML (хотя не существует требования, чтобы это выполнялось, эта возможность обеспечивает потенциальные преимущества обмена документов через посредников или накопление документов). Выигрыш от замены текста в кодировке base64 ссылкой на исходные данные уравновешивается увеличивающимся размером документа (уменьшение размера до 25% при обычной кодировке символов) и снижением производительности по сравнению с обработкой без непроизводительных потерь на кодирование и декодирование данных.

MTOM построен на XOP, сперва определяя абстрактную модель использования XOP для обработки сообщения SOAP, затем адаптируя эту модель для использования с MIME Multipart/Related пакетированием, и, наконец, применяя ее к транспортному протоколу HTTP. В целом это обеспечивает стандартный способ применения XOP к сообщениям SOAP, используя широко распространенный протокол передачи данных HTTP.

AXIOM поддерживает XOP/MTOM через интерфейс org.apache.AXIOM.om.OMText и его реализации. OMText определяет методы для поддержки текстовых элементов на основе двоичных данных (в виде части javax.activation.DataHandler, интерфейса Java Activation API часто используется для поддержки приложений данных в средах Java Web-ссервисов), используя также флажок "optimize", сообщающую, может ли элемент быть обработан с использованием XOP. Реализация org.apache.AXIOM.om.impl.llom.OMTextImpl добавляет MTOM-совместимый идентификатор ID содержимого, который может быть задан при создании экземпляра класса или сгенерирован автоматически, если не был задан.

В Листинге 6 показано, как создавать сообщение, используя XOP/MTOM в AXIOM. Данный программный код взят из примера отладки рабочих показателей, в котором используется сериализация Java для преобразования структур данных результата в массив из байтов и возвращения его в качестве двоичного приложения.

Листинг 6. Создание сообщения XOP/MTOM
    public OMElement matchQuakes(OMElement req) {
        Query query = new Query();
        Iterator iter = req.getChildElements();
        try {
            ...
            // извлекаем подходящее землетрясение
            Response response = QuakeBase.getInstance().handleQuery(query);
            
            // выстраиваем ответ в массив из последовательности байтов
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(response);
            byte[]byts = bos.toByteArray();
            
            // генерируем сьруктуру ответа с указанием на дату
            ByteArrayDataSource ds = new ByteArrayDataSource(byts);
            OMFactory fac = OMAbstractFactory.getOMFactory();
            OMNamespace ns =
                fac.createOMNamespace("http://seismic.sosnoski.com/types", "qk");
            OMElement resp = fac.createOMElement("response", ns);
            OMText data = fac.createOMText(new DataHandler(ds), true);
            resp.addChild(data);
            return resp;
            
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

Хотя код в Листинге 6 генерирует ответ, который может быть передан с помощью XOP/MTOM, в настоящей версии Axis2, поддержка XOP/MTOM отключена по умолчанию. Для ее включения необходимо включить параметр <parameter name="enableMTOM">true</parameter> в состав либо файла Axis2 axis2.xml, либо файла services.xml вашего сервиса. Полный текст программы для данного примера будет приведен в одной из следующих публикаций при сравнении рабочих характеристик, здесь же мы ограничимся примером XOP/MTOM в действии.

В Листинге 7 показана структура ответного сообщения, сгенерированного в Листинге, с XOP/MTOM или без него (без заголовков MIME и абсолютного двоичного приложения в первом случае, и с пропуском большей части данных во втором случае) при включенной поддержке XOP/MTOM.

Листинг 7.Ответное сообщение с XOP/MTOM или без него
<?xml version='1.0' encoding='UTF-8'?>
  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header />
    <soapenv:Body>
      <qk:response xmlns:qk="http://seismic.sosnoski.com/types"
          xmlns:tns="http://ws.apache.org/axis2">
        <xop:Include href="cid:1.urn:uuid:966CA4565647BEBA3D115028348657315@apache.org"
            xmlns:xop="http://www.w3.org/2004/08/xop/include" />
      </qk:response>
    </soapenv:Body>
  </soapenv:Envelope>
[actual binary data follows as separate MIME part with referenced content id]

<?xml version='1.0' encoding='UTF-8'?>
  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header />
    <soapenv:Body>
      <qk:response xmlns:qk="http://seismic.sosnoski.com/types"
          xmlns:tns="http://ws.apache.org/axis2">rO0ABXNyACdjb20uc29zb...</qk:response>
    </soapenv:Body>
  </soapenv:Envelope>

-

Добавочные блоки привязки данных

Большинству разработчиков, работающих с Web-сервисами, приходится чаще работать с данными в виде объектов Java, чем XML документов (или даже документных моделей, таких как AXIOM). Среды разработки последнего поколения, такие как Axis и JAX-RPC, имеют собственные механизмы привязки данных для осуществления конвертации из XML в объект Java и наоборот, но это решение имеет много ограничений. реализация привязки данных в средах Web-сервисов обычно не может конкурировать со специализированными системами привязки данных, поэтому пользователи, предпочитающие более надежный контроль обработки XML, вынуждены "интегрировать" среды, имеющие неэффективный код преобразования со специализированными системами. По этой причине Axis2 изначально создавался способным поддерживать "встраиваемые" системы привязки данных, использующие различные среды привязки данных.

Поддержка привязки данных использует настраиваемые расширения инструмента WSDL2Java, входящего в состав Axis2. Этот инструмент генерирует код связи Axis2, в основе которого лежит описание сервиса WSDL в виде подпрограммы для клиентской стороны и приемника сообщений для серсерной стороны. Клиентская подпрограмма действует как сервер-посредник для обращения к сервису, определяющий вызовы методов, выполняющих сервисные операции. Приемник сообщений серверной стороны действует как сервер-посредник для клиента, вызывающий нужный метод сервиса, заданный пользователем. Когда привязка данных запрашивается в командной строке WSDL2Java, инструмент вызывает специализированное расширение системы привязки данных для генерирования кода в подпрограмме или приемнике сообщений, позволяющее конвертировать элементы OMElement в Java объекты и наоборот. В случае подпрограммы объекты Java (или элементарные значения) передаются в методе вызова, и конвертированный XML отсылается серверу по запросу. Возвращенный XML затем преобразуется обратно в объект Java, который затем возвращается как результат метода вызова. Приемник сообщений серверной стороны выполняет те же преобразования в обратном порядке.

На входной или непередающей стороне (преобразование полученного XML в объекты Java), управление несложно. Информация документа XML, предназначенная для преобразования в объекты Java доступна в виде элемента OMElement, и система привязки данных должна лишь обработать данные этого элемента. OMElement предоставляет доступ к данным элемента в виде StAX javax.xml.stream.XMLStreamReader, которые в этой форме большинство современных систем привязки данных могут использовать напрямую как входную информацию.

На выходной или передающей стороне (преобразование объектов Java в передаваемый XML) эта процедура несколько сложнее. Суть AXIOM в уклонении от построения полного представления данных XML при отсутствии абсолютной необходимости этого. Для поддержки этого принципа при трансляции должен быть способ вызова системы привязки данных только при необходимсости. AXIOM решает эту проблему, используя org.apache.AXIOM.om.OMDataSource как оболочку для преобразования данных. OMDataSource определяет методы для записи содержимого оболочки, используя методы, поддерживаемые AXIOM (java.io.OutputStream, java.io.Writer или StAX javax.xml.stream.XMLStreamWriter), с другим методом, который возвращает экземпляр парсера содержимому оболочки. Реализация OMElement может использовать экземпляр OMDataSource для поддержки данных по требованию, а интерфейс OMFactory обеспечивает метод для создания элемента этого типа.


Рабочие характеристики

Мы закончим рассмотрение AXIOM кратким обзором его рабочих характеристик. При написании данной статьи была доступна версия AXIOM 1.1, что означает, что описанные в ней интерфейсы должны оставаться постоянными. Рабочие характеристики, с другой стороны, со временем меняются, так как меняется программный код реализации. Мы не думаем, что обнаружим принципиальные отличия в рабочих характеристиках AXIOM по отношению к другим моделям документов, но весьма вероятно, что некоторые отличия все-таки есть.

Для сравнения AXIOM с другими объектными моделями, мы обновили код, приведенный в вышедшей ранее статье по моделям документов (см. раздел Ресурсы), добавив AXIOM и еще одну новую документную модель (XOM), преобразовав код для использования стандартов парсера StAX, вместо более раннего стандарта SAX, и перейдя на улучшенный метод System.nanoTime() измерения времени, введенный в Java 5. Программа тестирования рабочих характеристик сперва считывает документ, который будет использован в программе, в память, замет выполняет всю последовательность операций над документом. Сначала создается некоторое количество копий представления документа из парсера, и каждый результирующий объект документа удерживается в памяти. Затем каждый объект документа "проходится,", то есть программа сканирует все представление документа (включая все атрибуты, значения и текстовое содержимое). Наконец, каждый объект документа записывается в выходной поток. Фиксируется как время выполнения каждой отдельной операции, так и среднее в конце отладочного теста.

Поскольку основное внимание AXIOM (особенно при его использовании в Axis2) уделяется обработке сообщений SOAP, мы взяли три разных совокупности тестовых сообщений SOAP для оценки рабочих характеристик. Первый образец - ответное сообщение от рабочих испытаний Web-сервиса, который несет информацию о землетрясениях за определенный период времени и диапазон широт/долгот ("землетрясения," 18 KB). Этот документ содержит много повторяющихся элементов с вложениями и избыточным использованием атрибутов. Второй образец - более объемный пример, взятый из теста на интероперабельность Microsoft WCF, состоящий из одной структуры, повторяющейся с незначительными вариациями в значениях ("персонал," 202 KB). Этот документ имеет дочерние элементы с текстовым содержимым, но без атрибутов. Третий тестовый образец - коллекция из 30 маленьких документов SOAP сообщений (сообщения), взятый из одного из старых тестов интероперабельности (общий объем 19 KB). Все свободное пространство для форматирования было удалено из тестовых документов, чтобы они могли имитировать XML обмен настоящего сервиса (который обычно отключает форматирование, чтобы уменьшить размеры сообщений).

Приведенные ниже диаграммы показывают среднее время, требуемое для 50 прохождений каждого документа. В качестве тестовой среды была выбрана система Compaq notebook с процессором 1600 MHz ML-30 AMD Turion и объемом RAM 1.5 GB, работающая под Sun's 1.5.0_07-b03 JVM на Mandriva 2006 Linux. Мы протестировали AXIOM 1.0, dom4j 1.6.1, JDOM 1.0, Xerces2 2.7.0, и XOM из дистрибутива Nux 1.6. Типовые конструкторы для парсеров StAX использовались для dom4j, JDOM и Xerces2 и конструктор парсера Nux StAX для XOM. Для всех тестов использовался парсер Woodstox StAX 2.9.3.

На Рисунке 1 показано суммарное среднее время, необходимое для двух первых этапов в тестовой последовательности, построение документа из парсера, прохождение представления документа для проверки содержимого. Если рассмотреть первый этап отдельно от второго (время здесь не указано), AXIOM показывает гораздо лучшие результаты, чем другие документные модели, по крайней мере для первых двух документов. Тем не менее, это просто подтверждает, что AXIOM работает так, как и ожидалось, и в действительности не строит полностью документ без необходимости. Мы же хотели оценить время, затрачиваемое на построение полного представления в памяти, просто для сравнения, вот почему два показателя времени в данной диаграмме суммируются.

Рисунок 1. Время создания и развертывания документов (в миллисекундах)
Время создания и развертывания документов

Как показано на рисунке 1, AXIOM медленнее всех тестируемых моделей, кроме Xerces2.

У нескольких моделей документов возникли проблемы при обработке коллекций документов малого размера ("сообщения"). Xerces2 показал особенно низкие результаты в этом случае, но AXIOM также продемонстрировал высокие непроизводительные издержки, что, возможно, является наиболее тревожным показателем в данной диаграмме. Небольшие сообщения - обычное явление для многих Web-сервисов, и AXIOM должен быть в состоянии эффективно их обрабатывать. Принимая во внимание, что AXIOM был специально предназначен для расширения дерева по требованию, временные показатели для двух более крупных документов не представляют большого интереса, поскольку они по крайней мере близки к показаниям моделей документов.

Рисунок 2. Время записи документа (в миллисекундах)
Время записи документа

На рисунке 2 показано среднее время записи документов в выходной поток для каждой модели. Здесь наилучшие результаты показаны Xerces2 при значительном отрыве от других моделей (но этих результатов не достаточно, чтобы перекрыть его низкие показатели на этапе построения; шкалы двух графиков разные), а наихудшие принадлежат AXIOM. Здесь также AXIOM демонстрирует особенно неудовлетворительные результаты при работе с маленькими документами.

Рисунок 3. Объем памяти, занимаемый документом (в KB)
Объем памяти, занимаемый документом

Наконец, на рисунке 3 показан объем памяти, используемый каждой из сред для представления документов. dom4j снова показывает заметно лучшие результаты, а AXIOM самые худшие со значительным отрывом. Отчасти низкие показатели AXIOM в отношении использования памяти объясняются тем, что на анализатор ссылается создаваемый документ, поэтому удерживается в памяти столько, сколько используется документ. Отчасти поэтому AXIOM снова имеет особенно неудовлетворительные показатели при работе с маленькими документами. Тем не менее, объекты, используемые AXIOM как компоненты документа, также значительно больше по объему, чем соответствующие им компоненты других моделей. Это отличие объясняет, почему AXIOM использует гораздо больше места даже для больших тестовых документов (где фиксированные издержки для анализатора и других структур данных меньше в пропорции к общей загрузке памяти).

Если вы сложите время из первых двух диаграмм, в целом лидером окажется dom4j, а самым медлительным Xerces2 (и AXIOM лишь ненамного впереди последнего). По использованию ресурсов памяти dom4j снова оказывается самым лучшим, но в данном контексте AXIOM проигрывает абсолютно. Звучит обезнадеживающе для AXIOM?

Это было бы безнадежно, если бы каждый раз строилось полное дерево представления, но помните, что суть AXIOM в том, что часто полное представление не требуется. На рисунке 4 показано время построения документа на начальном этапе в AXIOM в сравнении с соответствующим временным показателем для других документных моделей при построении представления документа. Здесь AXIOM справляется с задачей гораздо быстрее других моделей (слишком быстро даже, чтобы зарегистрировать, в случае двух более крупных документов). Такое же соотношение имеет место при оценке загрузки памяти. При работе в сети, где вам часто приходится работать лишь с частью документной модели ("первой" частью, с порядковой точки зрения документа), AXIOM демонстрирует отличные рабочие показатели.

Рисунок 4. Первоначальная структура документа
Размеры памяти документа

Дальше об Axis2

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

Теперь вы знаете, как Axis2 обрабатывает представления сообщений SOAP, используя AXIOM, в том числе, как он передает XML системе привязки данных и получает его обратно. В следующей статье будет рассмотрена работа поддержки Axis2 различных систем привязки данных с точки зрения пользователя, приведены примеры программных кодов с использованием трех сред разработки.


Загрузка

ОписаниеИмяРазмер
Code used for the performance tests in the articlecode.zip98KB

Ресурсы

Научиться

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

  • Создайте свой следующий проект при помощи пробного ПО IBM , загрузить которое можно с developerWorks.
  • Объектная модель документа dom4j - быстрая, рационально использующая память и обладающая большой расширяемостью модель.
  • Объектная модель документа JDOM известна простотой использования.
  • Объектная модель документа XOM предотвращает совершение обычных ошибок пользователей при работе с XML и обеспечивает хорошую производительность и рациональное использование памяти.
  • Nux - проект с открытым программным кодом по разработке ПО промежуточного слоя высокоскоростной обработки сообщений XML, направленный на интеграцию лучших среди аналогов компонентов для обработки XML в один инструментальный набор.
  • Xerces2 - реализация Apache стандарта объектной модели документа W3C.
  • Получите самую новую документацию по Apache Axis2 и файлы для загрузки.
  • WoodStox - реализация парсера StAX с открытым программным кодом.

Обсудить

Комментарии

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=SOA и web-сервисы, Технология Java
ArticleID=210004
ArticleTitle= Web-сервисы Java, Часть 2: Погружение в Axis2: AXIOM
publish-date=04172007