Вы находитесь на странице: 1из 74

Шпаргалка по SCDJWS

Выполнен Krocodl, 2010 год. Бесплатен для любого некоммерческого использования. Все вопросы, замечания и
предложения на krocodl@yandex.ru

Общее
• WS-I Basic Profile 1.0 включает – XML1.0, SOAP 1.1, WSDL 1.1,UDDI – опционально
• API – JAX-RPC 1.1, SAAJ, JAXR 1.0, JAXP 1.0, DOM 2, SAX 2
• В J2EE 1.4 входят следующие API – SAAJ, JAX-RPC, JAXP, JAXR
• JAXP
• входит в оба типа API, а JAXB – ни в одно не входит
• включает в себя – SAX, DOM, XSLT
• плагинно ориентированное API для доступа к различным механизмам обработки XML
• WS-I
o Представляет набор правил использования и организации веб сервисов
o Делает их доступными для использования с любой платформы
o Объединяет спецификации XML, SOAP, WSDL и UDDI
• Категория веб-сервиса – это бизнес информация !!!!
• STAX (Streaming API for XML) к JAXP не относится и в область экзамена не входит
• URL адрес точки доступа может быть задан динамически, то есть в вопросе имеется в
виду клиент
• Service provider task – register a service, client tasks – find, bind and invoke
• J2EE должна как минимум предоставлять – один SAX парсер, один DOM парсер и одну
XSLT механизм преобразования
• BP поддерживает только SOAP 1.1, НЕ путать с SOAP 1.2

XML и Schema

Общие замечания
o «Well-formed» - документ соответствует стандартам XML в части синтаксиса, то
есть использования тегов.
o «Valid» - соответствует какому-то языку на основе XML, то есть DTD или схеме
o Valid => Well-formed

Синтаксис XML
o Заголовок
 <?xml version=”” encoding=”” standalone=”yes|no” ?> - форматом не
требуется
 «<» - первая буква в файле
 Порядок существенен
 Version – единственный обязательный атрибут, поддерживается только 1.0
 Encoding
• по умолчанию UTF-8
• при получении через HTTP может использоваться кодировка в
пакете, а не в документе
 Кодировки в соответствии с BP – UTF-8 и UTF-16
o XML парсер при загрузке преобразует CRLF в LF
o Атрибуты
 могут идти в любом порядке, но каждый только один раз
 можно определить «def» значения, для элементов нельзя
o Наименование элементов и атрибутов:
 начинаются только с буквы или «_»
 дальше все, что представимо в uuencode, в том числе и цифры
 никогда не начинается с «xml», причем в любом исполнении
 «:» - может встретиться только один раз при указании пространства имен
o Элементы
 Перед закрывающим «>»может встретиться « », после открывающей «<» -
нет
 Тип содержания – mixed, simple, element, empty
 Что угодно внутри - <![CDATA[…]]>
o В комментариях не может использовать «-» или «--»
o В качестве схемы поддерживается только W3C XML Schema
o Инструкция обработки
 Формат - <?наименование_инструкции что_угодно?>
 Наименования, начинающиеся с «xml» - зарезервированные
 Подсказки для специфических обрабатывающих приложений

Namespaces – пространство имен


o Определяются через УИД набора уникальных имен в виде
 Некоторого URL, реального обращения по нему никогда не происходит,
просто УИД
 Некоторого URN в формате – urn:<namespace_id>:<uid>
o Служат для формирования специализированных языков на основе XML
o Определение использования – от элемента вниз
 По умолчанию в дальнейшем для тегов без префиксов – xmlns=”URI”, на
него ссылаются как на “default namespace”. Если дефолтное пространство
не определено, то подразумевается, что это URL данного документа
 Для тегов на основе префикса – xmlns:prefix=”URI”
 Определения не попадают в коллекцию атрибутов при парсинге
 Prefix:element – Qname, qualified name. Состоит из ссылки на пространство
и локального имени
 Для пространства через префикс можно перегрузить. Отменить нельзя
(только в XML 1.1)
 Для дефолтного пространства можно перегрузить и отменить xmlns=””
o Используются для
 Разделения тегов по языкам, в которых они определены. Разные языки
могут привязываться к разным обработчикам
 Использование версий для языков
o Дефолтное пространство относится только к элементам, для атрибутов смысла
не имеет и должно указываться явно
o Два атрибута одного элемента с одинаковым именем и относящихся к одному
пространству имен (м.б. через разные префиксы) существовать не могут.
Однако возможно, если один с префиксом, а другой без, когда пространства
дефолтное и с префиксом одинаковы. Так как атрибуты не относятся к
дефолтному пространству
o Использование API для определения элемента в пространстве имен

public class QName implements java.io.Serializable {


public QName(String localPart) {...}
public QName(String namespaceURI, String localPart){...}
public String getNamespaceURI(){...}
public String getLocalPart(){...}
public static QName valueOf(String qualfiedName){...}
}
Определение схемы
o DTD ограничивают элементы в использовании других элементов и содержания
(ничего или текст). А также в списке атрибутов. Нет ограничения на типы данных
o XSD определяет структуру документа и определяет набор типов данных
o Один схема документ может определять несколько пространств имен
o Родительский элемент – schema(element*,attribute*, simpleType*, complexType*,
group*), у него атрибуты:
 Xmlns:xsd="http://www.w3.org/2001/XMLSchema" – пространство имен,
определяющее синтаксис самой схемы, префикс «xsd» - стандартный
 targetNamespace="newUri" – наименование пространства имени для
определяемой схемы
 xmlns:prefix="newUri” – определяем префикс, чтобы ссылаться на
объекты определяемой схемы. В частности, когда определяем элементы
наших типов надо использовать QName с данным префиксом
 elementFormDefault / attributeFormDefault – должны ли локальные
элементы и атрибуты в XML документы быть qualified = qualified |
unqualified. По умолчанию unqualified. Глобальные элементы должны быть
qualified всегда
o Глобальные определения:
 Элементы, каждый из которых определяет тип XML документа, который
соответствует схеме. Глобальные элементы должны быть qualified, если
они не принадлежат основной схеме
 Глобальные атрибуты – может употребляться в любом элементе схемы.
Должны быть qualified всегда
 Группы совместно используемых атрибутов
 Через ref/href их можно многократно включать далее по тексту.
Соответственно используются встроенные типы данных xsd:ID и
xsd:anyURL
o Встроенные типы данных
 Используются с префиксом пространства – xsd:
 Boolean (true | false | 0 | 1), byte, short, int, long, float, double, string
 decimal (java.math.BigDecimal)
 date, time (java.util.GregorianCalendar) и dateTime (java.util.Date)
 base64binary (byte[]) и hexBinary (byte[])
 anySimpleType (String)
 any (javax.xml.soap.SOAPElement)
o Определение сложного типа – complexType(sequence*, all*, choice*)
 Атрибуты определения типа:
• Name - наименование
• Abstract = true | false – необходимость наследования
• Final = restriction | extension | #all – опции наследования
 Контейнер, внутри элементы, контейнеры или группы (ссылки на глобально
определенные группы) в произвольных комбинациях
• Контейнер sequence(element*) – элементы в точном порядке и в
любом количестве каждый.
• Контейнер all(element*) – в любом порядке
o Всегда употребляется только на верхнем уровне вложенности
внутри типа
o каждый может встретиться 0|1 раз
o не может содержать вложенные сложные контейнеры –
sequence или all
• Контейнер choice(element*) – один из вложенных элементов или
контейнеров. К нему применимы атрибуты minOccurs и maxOccurs
 Определение элемента внутри контейнера (или глобальный) – element, для
него атрибуты:
• Name – наименование
• Type – тип, встроенный или простой / сложный. В последнем случае
используется QName.
o Вместо типа можно при помощи вложенного элемента
complexType определить тип на месте.
o Вместе type и complexType использоваться не могут
o Если вложенное определение типа имеет имя, то может быть
использовано повторно
• Количество появлений – minOccurs и maxOccurs, по умолчанию
«1». Неограниченное количество раз – «unbounded»
• Nillable – элемент может быть пустым без проблемы с валидацией.
o Внутри такого элемента в XML документе нужно указать
атрибут xsd:nil=”true” (можно также 0 / 1)
o Если определен, то в jave должен использоваться не
примитив, а обертка
 Вместо элемента внутри контейнера можно определить использование
любого элемента - <any>.
• Могут использовать атрибуты minOccurs и maxOccurs
• В java это отвечает определению javax.xml.soap.SOAPElement[]
 Определения атрибутов – xsd:attribute, для них атрибуты:
• Name – наименование
• Type – тип
• Use – необходимость required | optional | prohibited | fixed
• Default – значение для умолчания, имеет смысл только для
«optional» атрибута
o Определение наследования – элемент «complexContent», внутри элементы
Extension | Restriction, единственный атрибут base – наименование базового
типа
 Extension – расширение базового класса определяемыми внути
элементами и атрибутами
 Restriction – часть элементов и атрибутов переопределяем, остальное
остается как есть. Не всегда корректно поддерживается языками
программирования, не совместимо с BP
 Внутри Extension | Restriction идет определения добавленных или
измененных контейнеров и атрибутов
o Определение простого (ограничение встроенного) типа – simpleType
 Атрибуты те же, основной – name
 Определение ограничения – элемент restriction с атрибутом base.
• Внутри элементы типа ограничения – length, minLength, maxLength,
whitespace, maxInclusive, maxExclusive, minInclusive,
minExclusive, pattern, enumeration, totalDigits, fractionDigits. (все с
префиксом xsd:)
o Основной атрибут элемента ограничения – value.
o Элементов ограничений может быть много, одинаковых
(перечисление) или разных
 Определение списка значений простого типа – элемент list, основной
атрибут itemType. В XML отдельные значения разделяются пробелами
 Определение списка значений простых типов типа – элемент union,
• основной атрибут itemTypes в котором наименования простых
типов разделяются « ».
• Отличие в том, что union может содержать набор значений одного
ИЛИ другого простого типа
• Сложные типы внутри не поддерживаются
o Sequence и choice могут вкладываться друг в друга в любом порядке. All не может
вкладываться внутри любого из них
o Импорт одной схемы внутрь другой
 Синтаксис - <import namespace=”URI” schemaLocation=”URL”>
 schemaLocation – опциональный атрибут
 Затем namespace используем для определения префикса, а префикс для
доступа к типам
o Включение части схемы в схему
 Синтаксис - <include schemaLocation=”URL”>
 Обе схемы имеют один и тот же targetNamespace, один файл продолжает
определение схемы, начатое во включаемом файле

Использование схемы
конфигурируется в корневом элементе (в общем-то не обязательно, но довольно часто)
документа следующими атрибутами
o Hint использования далее загрузки схемы в документе из внешнего испочника -
xmlns:xsi = http://www.w3.org/2001/XMLSchema-instance
o Определение переченя Uri схем, используемых в документе для загрузки
 С привзяыванием - атрибут xsi:schemaLocation=”…”. Внутри парами идут
– <Uri схемы> <физическое расположение схемы в виде URL>
 без привязывания к URL – атрибут xsi:noNamespaceSchemaLocation
o Xmlns=”Uri” – какая схема используется по умолчанию
o Xmlns:prefix=”Uri” – префиксы использования остальных схем
o Для любого элемента и ниже лежащих используемые схемы можно
переопределить
o Можно отказаться от использования основной схемы – xmlns=””, отказаться от
префикса, то есть Xmlns:prefix=”” – нельзя
o Атрибуты без префикса не принадлежат ни к одному пространству, даже к
дефолтному
o Везде, где может применяться тег-родитель может использоваться тег-наследник.
Изменение типа достигается атрибутов xsd:type=”QName элемента наследника”

XML API – JAXB

Общие замечания
o Средство переноса данных XML=U=>Java и Java =M=>XML
o Есть попытки поймать, когда говорят о маршаллинге из XML документа в Java
объекты или наоборот
o Настраивается либо через аннотации, либо через файл кастомизации
o Работает посредством специально XJC компилятора, строящего из схемы
исходники классов и фабрики
o Валидация происходит
 обязательно при U, но может быть отключенва
 по запросу может быть осуществлена для всего дерева объектов или его
фрагмента.
 Не производится при каждом расширении дерева бинов
o Пример использования – пользователь заполняет форму, затем в бины, которые
проверяются на оответствие схеме
o Не поддерживаются
 Элементы – xs:any, xs:anyAttribyte, xs:key, xs:h=keyRef, xs:unique
 Атрибуты – complexType.abstract, xsi:type, complexType.final
Основные интерфейсы
o Общие методы
 Get/set Property в виде String/Object
 Get/set EventHandler в виде ValidationEventHandler
o Unmarshaller
 Object unmarshal(File | InputStream | URL | InputSource | Node | Source)
• Не может считывать непосредственно из Stream
 Get/set Validating в виде boolean
o Marshaller
 Marshal(Object, Result | OutputStream | Writer | ContentHandler | Node)
 Node getNode(Object)
o Validator
 Validate(Object) и ValidateRoot(Object)

Использование
o Создается XML схема, из нее получается:
 URI пространства имен => java пакет
 Complex type => java interface
 Enumeration в составе простого типа => java enum
 Глобальный элемент => java Element Interface
 Атрибуты, локальные элементы => члены классов
 Встроенный тип xsd:anySimpleType => String
o XJC компилятор из схемы генерирует классы в определенном пакете:
 ObjectFactory – реализация фабрики создания контекста,
расширяет .DefaultJAXBContextImpl
 Публичные интерфейсы, соответствующие типам данных в схеме
 В дочернем пакете Impl – имплементации интерфейсов. Напрямую объекты
данных классов создавать нельзя – только через фабрику ObjectFactory
o Создается контекст – входная точка для работы
 JAXBContext jc = JAXBContext.newInstance("com.a:com.b" );
 Основной параметр – перечень пакетов, в которых лежат интерфейсы
сгенерированных классов через «:»
 В каждом таком пакете должен быть сгенерированный файл
• jaxb.properties, в котором есть свойство
javax.xml.bind.context.factory, определяющее класс реализацию
контекста. Реализация должна поставлять метод JAXBContext
createContext(strContextPath, classLoader)
• bgm.ser
o XML =U=>Java
 Пример
Unmarshaller u = jc.createUnmarshaller();
FooObject fooObj = (FooObject)u.unmarshal( new File( "foo.xml" ) );
 Можно включить валидацию эквивалентности XML структуры и дерева
объектов во время загрузки - Unmarshaller.setValidating()
 Можно использовать в качестве источника данных поток событий от SAX
o Создание объектов с нуля
ObjectFactory objFactory = new ObjectFactory();
FooObject fo = objFactory.createFooObject();
o Работа с ошибками
 Можно проверить дерево объектов или его фрагмент –
Validator.validate().
Validator v = jc.createValidator();
boolean valid = v.validateRoot( po );
 Также ошибки можно получать за счет подключения
ValidationEventHandler к анмаршаллеру или валидатору
 Есть валидатор по умолчанию – прекращает разбор в случае критических
ошибок. Остальное пропускает
 Пропущенное можно получить с помощью ValidationEventCollector
утилиты
o Java =M=>XML
Marshaller m = jc.createMarshaller();
m.marshal( fooObj, System.out );

Кастомизация
o Используемое пространство имен – http://ajav.sun.com/xml/ns/jaxb
o Два пути – встраиваем в схему или кладем рядом
o Зачем:
 Javadoc для генерируемого кода
 Разрешение конфликтов имен
 Работа с именами, которые не являются стандартными java
идентификаторами
 Наименования для безымянных групп, которые мапятся на свойства или
классы
 Определение имплементации для коллекций
 Соотнесение фиксированных атрибутов и java констант
o Содержание – <jaxb:xxxx ……. >
o Встроенная - внутри аннотации для схемы xs:annotation / xs:appinfo
o Отдельная
 корневой элемент <jaxb:bindings>
 К нему атрибут – что аннотируем
• schemaLocation=”URI”
• node=”XPath к фрагменту схемы”

XML API – SAX2

Общие замечания
o Основные пакеты - org.xml.sax.* и org.xml.sax.hepleers.*
o Предполагает использование DTD, поэтому поддержка схем есть опциональная
возможность, которую надо специально включать за счет parser.setFeature(URI,
bool) или parserFactory.setNamspaceAware(true)
o Опциональные возможности можно конфигурировать за счет
parser.setProperty(URI,String)
o В принципе может выстаскивать комментарии и подобные излишества при
помощи LexicalHandler, но это не стандартная feature
o Тип фабрики парсера определяется на основе переменной
javax.xml.parsers.SAXParserFactory из следующих источников:
 Системное свойство (мб через аргументы запуска)
 Через свойство в файле $JAVA_HOME$/lib/jaxp.properties
 Через файл с данным именем в META-INF/services
Если не нашли – используем системный, заданный по умолчанию
o Установка текущего парсера для дефолтной фабрики – через переменную
org.xml.sax.driver
o Используем когда:
 Надо обработать только часть документа
 Документ надо обработать только один раз
 Мало памяти
 Нет необходимости потом редактировать документ
 Надо получать доступ к элементам по мере процесса обработки –
событийно ориентированная обработка

Использование
o Через XmlReader
XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setContentHandler(new SimpleHandler())
reader.parse(fileName) или reader.parse(InputSource)

o Через XmlParser
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();

XMLReader reader = saxParser.getXMLReader();


reader.setContentHandler(new SimpleHandler())

reader.parse(fileName)
Или
saxParser.parser(filename, new SimpleHandler());
o Установка перечня используемых возможностей, в частности, что будут
создаваться события о регистрации префиксов пространств наименований и
проверяться соответствие схемам
parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
parser.setFeature("http://apache.org/xml/features/validation/schema-full-
checking",true);
o Установка использования пространства имен
// на уровне фабрики
saxParserFactory.setNamespaceAware(true);
// на уровне конкретного парсера
parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
parser.setFeature("http://xml.org/sax/features/namespaces", true);
o Конфигурирование дополнительных возможностей. В данном случае установка
расположения схем
parser.setProperty(
"http://apache.org/xml/properties/schema/external-schemaLocation",
"http://schemas.xmlsoap.org/soap/envelope/ SOAP-1_1.xsd "+
"http://www.Monson-Haefel.com/jwsbook/BookQuote bookquote.xsd");
o Собственно парсинг
parser.parse(fileName);

Обработчик событий
o Реализует org.xml.sax.ContentHandler (DefaultHandler – дефолтная
реализация). Почти все методы возбуждают SAXException
o void startDocument()
o void endDocument()
o void setDocumentLocator(Locator locator) – установка объекта, позволяющего в
интересах лога и отладки узнать где сейчас в документе мы находимся.
SAXException не возбуждает
o void startElement(String namespaceURI, String localName, String qName,
Attributes atts) – начало элемента
 namespaceURI – полный URI пространства имен
 localName – имя без префикса
 qName имя с префиксом
 atts – перечень атрибутов, порядок может не совпадать с порядком в
документе, основные методы:
• int getLength ();
• int getIndex(String uri, String localPart);
• int getIndex(String qName);
• String getLocalName(int index);
• String getQName(int index);
• String getURI(int index);
• String getValue(String uri, String localName);
• String getValue(String qName);
• String getValue(int index);
• String getType(String uri, String localName);
• String getType(String qName);
• String getType(int index);
o void endElement(String namespaceURI, String localName, String qName)
o void startPrefixMapping(String prefix, String uri) – начало ассоциации префикса с
URI пространства имен. Вызывается перед startElement.
o void endPrefixMapping(String prefix) – аналогично, вызывается после
endElement
o void characters(char[] text, int start, int length) - когда элемент содержит текст.
Может вызываться много раз, если для обработки текста используется буфер
фиксированной длинны, а текст большой
o void ignorableWhitespace(char[] text, int start, int length) – регистрация пустого
пространства между документами
o void processingInstruction(String target, String data) - обработка XML
инструкций, BP запрещает их использование, не требуется
o void skippedEntity(String name) – вызывается для пропускаемых сущностей в
DTD, BP не использует DTD, не надо

Разпознование ссылок на внешние сущности


o Используется в целях
 Безопасности
 Отказоустойчивости
 Ускорения
 реализация загрузки из нестандартных источников, например СУБД
o Часто совмещается с кэшированием
o Реализуется через реализацию EntityResolver
 единственный метод InputSource resolveEntity(publicId, systemId)
 Если не найдено, то надо возвращать null
 Регистрируется как xmlReader.setEntityResolver(…)

XML API – DOM2

Общие замечания
o Основные пакеты - org.w3c.dom.*
o JAXP API введено для унификации разницы между разными парсерами
o Основной тип данных – Node, от него все остальные – Document, Attr, Text,
Comment, CDATASection и так далее
o Единственный API, позволяющий вытаскивать из документа все, включая
пробелы и комментарии
o Тип фабрики парсера определяется на основе переменной
javax.xml.parsers.DocumentBuilderFactory из следующих источников:
 Системное свойство (мб через аргументы запуска)
 Через свойство в файле $JAVA_HOME$/lib/jaxp.properties
 Через файл с данным именем в META-INF/services
Если не нашли – используем системный, заданный по умолчанию

Использование
o Создание фабрики для построителя документов
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
o Установка использования пространства имен
factory.setNamespaceAware(true);
o Создание построителя документов - парсера
DocumentBuilder parser = factory.newDocumentBuilder();
o Создание пустого документа
Document xmlDoc = parser.newDocument()
o Загрузка и разбор документа
Document xmlDoc = parser.parse(FileInputStream(filePath));
o Получение рутового элемента
Element root = xmlDoc.getDocumentElement();
o Установка значения у атрибута элемента
root.setAttribute(name, value);
o Создание нового QName элемента
Element body = xmlDoc.createElementNS(NSName,value);
o Добавление одного элемента к другому
root.appendChild(body);
o Создание нового QName атрибута
Attr typeAttr = xmlDoc.createAttributeNS(NSName, attName);
typeAttr.setValue(attValue);
element.setAttributeNodeNS(typeAttr);
o Добавление текствого элемента
Text text = xmlDoc.createTextNode(textValue);
body.appendChild(text);
o Добавление CDATA секции
CDATASection cdata = xmlDoc2.createCDATASection(cdataValue);
element.appendChild(cdata);

Документ - Document
o Document – тоже расширение Node
o Document.importNode(Node, Boolean deep) - импорт Node из другого документа
o NodeList getElementsByTagName(String tagname) – получение элементов по
имени, допускается «*», метод наследован от Element
o Element getDocumentElement() – получение рутового элемента.

Основной строительный блок - Node


o Основные методы, сильно зависимые от типа элемента
 Document getOwnerDocument() – независимо от того, включена ли Node
в документ или нет, она к нему принадлежит. Просто так вставить в другой
документ нельзя. Даже если удалить из исходного.
 short getNodeType() - получение типа элемента, один из следующих,
заданных как static константа:
• CDATA_SECTION_NODE;
• COMMENT_NODE;
• DOCUMENT_FRAGMENT_NODE;
• DOCUMENT_NODE;
• DOCUMENT_TYPE_NODE;
• ELEMENT_NODE;
• ENTITY_NODE;
• ENTITY_REFERENCE_NODE;
• NOTATION_NODE;
• PROCESSING_INSTRUCTION_NODE;
• TEXT_NODE;
 String getNodeName();
 String getNodeValue() throws DOMException;
 void setNodeValue(String nodeValue) throws DOMException;
o Получение XML наименования
 String getLocalName();
 String getNamespaceURI();
 String getPrefix();
 void setPrefix(String prefix) throws DOMException;
o Работа с атрибутами
 boolean hasAttributes();
 NamedNodeMap getAttributes();
o Навигация
 Node getParentNode() – у документа родителя не существует, у
элемента – элемент или документ, у Attr, Text, Comment и CDATASection -
элемент
 boolean hasChildNodes() – у Document – рутовый элемент, у того
элементы, текст, СDATA или комментарии.
 Node getFirstChild();
 Node getLastChild();
 NodeList getChildNodes();
 Node getPreviousSibling() – для Text - другие его фрагменты, если
текст разбит на куски. Для Attr – другие Attr. Document и root Element – не
имеют
 Node getNextSibling();
o Управление содержимым
 Node appendChild(Node newChild) throws DOMException;
 Node replaceChild(Node newChild, Node oldChild) throws DOMException;
 Node removeChild(Node oldChild) throws DOMException;
 Node insertBefore(Node newChild, Node refChild) throws DOMException;
o Остальное
 Node cloneNode(boolean deep) – копировать просто или с содержимым,
полученное можно вставлять только в тот же документ
 void normalize() – убирание лишнего, приведение к нормальному
текстовому виду
 boolean isSupported(String feature, String version) – поддерживает ли
фичи типа XML схем, DTD или пространства имен
 Доступ к атрибутам
• getAttribute() method on Element
• the getAttributes() method on Node and iterate over the NamedNodeMap
• getAttributeNode() method on Element and access the value property on
Attr

XML API – XSLT и TrAX

Основы XSLT
o Входной и выходной документы интерпретируются в виде XPath модели данных.
Выбираются ветки из исходного документа, к ним применяются подходящие
шаблоны из таблицы преобразований и формируются ветки выходного документа
o Корневой элемент таблицы – xsl:stylesheet, в нем атрибуты определения
префикса - xsl и версии – version
o Шаблон – xsl:template, атрибуты:
 Match – условие на обрабатываемый шаблоном элемент входного
документа. «/» - корень документа
 Xml:space=”preserve” – сохранять пробелы в выходном документе
o В теле xsl:template – сам шаблон, внутри него:
 Xsl:param – определение параметра, атрибуты
• Name – ИД
• Select – дефолтное значение, также может быть определено в теле
определения. При вызове шаблона по ИД значение может быть
переопределено.
• Объект Transformer может их использовать:
o void setParameter(String name, Object value);
o Object getParameter(String name);
o void clearParameters();
o Не могут получить данные из XSLT таблицы, а только
работают с Java настройками процесса преобразования
 Xsl:variable – то же самое, что и param, но значение не переопределяется
 $name – ссылка на значение параметра или переменной по ИД. Ссылки не
типизируемые, то есть если значение не проходит по типу – исключение
процессора. Может использоваться внутри test атрибута.
 Xsl:value-of – вставка значения из исходного документа. Что вставлять
определяется по выражению XPath в атрибуте select
 Xsl:choose(xsl:when*, xsl:otherwise) – выбор из набора условий. Условие
определяется как атрибут test в элементе xsl:when
 Xsl:call-template – вызов шаблона по ИД, определяемому в атрибуте name.
• Внутри передаваемые значения в виде элементов xsl:with-param с
атрибутами name и select
• Особенно удобное при рекурсии, заменяет присваивание
переменных. Пример – печать чисел от 1 до N
 Xsl:apply-templates – выполнение преобразования от узла, задаваемого
как атрибут select
 Xsl:if – выполнение, если истинно значение атрибута test
o Определения параметров преобразования - xsl:output
 атрибуты с примерами значений:
• method="xml"
• encoding="UTF-16"
• indent="yes"
• media-type="text/xml"
• standalone="yes"
 Работа через API от объекта Transformer
• Возбуждают IllegalArgumentException
• void setOutputProperties(Properties)
• Properties getOutputProperties();
• void setOutputProperty(name, value)
• String getOutputProperty(name)
o Примеры XPath синтаксиса
 10 * params/param/value/int
 Not(params/param/value/int) &gt; 1
 Count(methodCall/params)
 Child::methodCall – указание на дочернюю ветку с определенным
наименование
o Xsl:import и xsl:include – работа с другими таблицами

TrAX - API
o Transformation API for XML – абстрагирование от особенностей процессоров и
типа источника / результата преобразования – XML потоки, SAX
последовательность событий, DOM дерево объектов
o Основные процессоры – Xalan и SAXON
o Пакет – javax.xml.transforms
o Основные артефакты:
 Templates – представление распарсенной XSLT таблицы.
• Является фабрикой для Transformer.
• Может использоваться в конкурентной среде.
• Должен использоваться в случае серверной работы с таблицами
 Transformer – преобразователь - представление таблицы преобразования,
транслирует данные из Source в Result.
• Может быть использован несколько раз.
• Не может использоваться в конкурирующих потоках
• Должен использоваться в однопоточной среде
 TransformerFactory – фабрика - представление XSLT процессора
• читает таблицу и создает Transformer или Templates
• Не может использоваться в конкурирующих потоках
 Source – источник данных для преобразования
• конструкторы на основе:
o Stream | DOM | SAX | JAXB
o Node
o ContentHandler
o InputStream
o Reader
o File
o String
• Есть дополнительное свойство – SystemID – лучше устанавливать
 Result – куда выливать преобразованное
o Определение используемого процессора по наименованию фабрики:
 Реализует javax.xml.transform.TransformerFactory
 Основные
• net.sf.saxon.TransformerFactoryImpl
• org.apache.xalan.processor.TransformerFactoryImpl
 Установить системную переменную
javax.xml.transform.TransformerFactory через SetProperty() или –D ключ
запуска JVM
 Хранить в файле lib/jaxp.properties в JRE директории
 В файле META-INF/services/javax.xml.transform.TransformerFactory в
доступном JAR
 Если не определено, то используется дефолтная реализация – Xalan
o XML документ в начале может иметь инструкцию о том, какие таблицы к нему
надо применять
 например для просмотра, в виде:
<?xml-stylesheet href="docbook-xsl-1.50.0/html/docbook.xsl"
type="application/xml" media="screen" title="HTML"
encoding="UTF-8" alternate="no"?>
 Можно получить за счет
TransformerFactory.getAssociatedStylesheet(Source, media, title, charset)
o Получение данных о совместимости процессора, доступности работы с разными
источниками данных и т.д.
 API - xformFactory getFeature(future)
 Возможности
• [Stream | DOM | SAX | JAXB]Source.FEATURE
• [Stream | DOM | SAX | JAXB]Result.FEATURE

TrAX - использование
 Создать фабрику процессора
TransformerFactory xformFactory = TransformerFactory.newInstance();
 Загрузить таблицу преобразования
Source xsl = new StreamSource("FibonacciXMLRPC.xsl");
 Для однопроцессной среды - создать преобразователь
Transformer stylesheet = xformFactory.newTransformer(xsl);
 Для многооднопроцессной среды
• создать скомпилированное представление таблицы (в одном потоке)
Templates templates = factory.newTemplates(xsl);
• Создать преобразователь в конкурентном режиме
Transformer stylesheet = templates.newTransformer();
 Создать объекты источника и назначения данных
Source request = new StreamSource(in);
Result response = new StreamResult(out);
 Выполнить преобразование – в одном потоке
stylesheet.transform(request, response);

WSDL 1.1

Общие замечания
o Специализирует – формат сообщения, протокол и адрес доступа. Фактически
представляет собой схему и даже имеет атрибут targetNamespace
o Корень definitions, в нем основные разделы:
 Import – импорт определений из других WSDL документов и схем. Должен
идти в обязательном порядке перед другими разделами, исключая
documentation
 Types – определение типов данных и элементов, которые будут
использоваться в других разделах. Реализуется на основе внедренных XML
схем и стандартных XSD типов. Должен идти до остальных разделов,
исключая Import и documentation
 Message / part – определение структуры сообщений (input / output / error) на
основе встроенных в XML схемы типов и типов, определенных в первом
разделе. Сообщение состоит из отдельных частей - part
 portType / operation – аналог интерфейсов и методов в языке.
Осуществляется на основе определения сообщений
 bindings – связывание, сопоставление интерфейсу (portType)
определенного протокола и стиля кодирования. Добавляются в описание
специфичные для SOAP элементы.
 service / port – определение сервиса как коллеции port – отдельных
серверных точек входа, связанных с bindings. Добавляются в описание
специфичные для SOAP элементы.
 documentation – входы в остальные разделы, в том числе в корневой,
которые содержат пояснения для специалистов
o BP требует чтобы
 Версия XML – 1.0
 Кодировка документа – UTF-8/16
 bindings и portType оперировали одним и тем же списком операций.
Требуется, чтобы были замаплены все операции.
 Документ соответствовал двум схема, при этом ответственность на
разработчике. То есть при использовании документ не проверяется.
o Располагается в поддиректории WSDL внутри war/jar файла
o Корневой элемент – definitions(documentation?, import*, types, message,
portType, binding, service), внутри все остальные определения,
 Определяет необходимые дальше пространства, минимум:
• Схема для основных типов данных -
http://schemas.xmlsoap.org/wsdl/
• Для формирования схем в разделе типов -
http://www.w3.org/2001/XMLSchema
• Для определения связывания -
http://schemas.xmlsoap.org/wsdl/soap/
 у него атрибуты:
• Name – наименование схемы, опциональный и на практике не
используется
• targetNamespace – пространство имен, в которое помещаются ИД-ы
сущностей всех основных разделов. В атрибуте name у таких
сущностей ИД-ы, а друг на друга они ссылаются через QName в
данном пространстве. Поэтому надо еще определить и префикс для
данного пространства, чтобы использовать в ссылках

Импорт другого WSDL документ – import


 Делает доступными в данном документе объекты из пространства имен
другого документа
 Синтаксис: <import namespace=”” location””>
• Namespace – в принципе не должен соответствовать
targetNamespace импортируемого документ, но BP этого требует
• Location – URL расположения, обязательный непустой атрибут.
o В отличии от импорта WSDL документа, при импорте схем
атрибут SchemaLocation – опциональный.
o Будет ли реальное обращение зависит от процессора – не
обязательно.
 Импорт должен идти обязательно перед определением в WSDL документе
своих типов
 Кроме импорта WSDL документа можно импортировать схему
• Но только из определения схемы внутри <schema> раздела типов:
<xsd:import namespace=" " schemaLocation="" />
• Импортироваться может только *.xsd файл, с корневым тегом
<xsd:schema> и namespace, совпадающим с targetNamespace WSDL
документа
• BP требует, чтобы
o Wsdl:import документ ссылался только на WSDL документы
o запрещает импорт лежащей отдельно схемы кроме как внутри другой схемы в
разделе типов через xsd:import
o Все импортируемое должно быть XML, совместимое с BP – 1.1 UTF-8/16
o targetNamespace импортируемого документ должен соответствовать его
содержанию и пространству имен WSDL документа
o могут использоваться только пространства определенные в документе или
явно импортированные. Импорт через импорт не поддерживается

Описание – documentation
o Может быть ребенком других определений, в том числе part
o Можеn быть первым ребенком definitions

Типы данных - types


o В принципе может служить контейнером для любых форматов определений
типов, но требуется WS-I использование XML схемы
o Определение типа –types(documentation?, xsd:schema*)
 контейнер для определения типов, которые будут использоваться в
дальнейшем – сложные типы и простые типы
 Внутри XML схема – xsd:schema, ее атрибут targetNamespace должен
иметься и соответствовать аналогичному атрибуту данного или
импортированного WSDL документа
 В SOAP 1.1 в соответствии с BP нельзя
• Использовать расширять или сужать soapenc:Array
• Использовать атрибут wsdl:arrayType в определении типа
• Использовать атрибут soapenc:arrayType в атрибуте сообщения
• называть свои массивы как ArrayOfXXX

Определение интерфейсов – message и portType


o Определение структуры сообщения –message(documentation?, part*)
 Может также определять структуру заголовка или сообщения об ошибке
 ИД задается атрибутом «name», из определения интерфейса ссылаться на
него надо в форме QName
 Для RPC сообщений структура набирается из нескольких частей, каждая
из которых типизирована при помощи атрибута «type» встроенным или
определенным до этого типом:
<message name="GetBookPriceRequest">
<part name="isbn" type="xsd:string" />
</message>
 Для doc-style, сообщений идет одиночная ссылка при помощи атрибута
«element» на рутовый элемент документа (то есть глобальный элемент в
схеме)
<message name="SubmitPurchaseOrderMessage">
<part name="order" element="mh:purchaseOrder" />
</message>
 Type и element вместе употреблены быть не могут
 В случае сообщения об ошибке в виде doc-style описывается структура
detail секции сообщения об ошибке. В принципе сообщение может нести
detail секцию не описанную в WSDL документе
 Part – соответствует параметру вызываемой функции, а message – набору
параметров
o Определение интерфейса – portType(documentation?,operation*)
 Атрибуты
• name
 Внутри определения отдельных операций в виде –
operation(documentation?, input?, output ?, fault*)
• Атрибуты
o Name – обязательный
• Внутри определения параметров:
o <input name="" message="prefix:id"/> - не больше одного
элемента
o <output name="" message="prefix:id"/>- не больше одного
элемента
o <fault name="" message="prefix:id"/> - любое количество
элементов, может не быть вовсе
o они в принципе могут иметь атрибут name
• Для операции может задаваться единый порядок частей внутри
параметров за счет атрибута parameterOrder.
o Включает input и output part кроме той, которая возвращается
методом как return (может отсутствовать, тогда void)
o Порядок part соответствует порядку параметров в сигнатуре
метода реализации
o В могут parameterOrder упоминаться IN, OUT, INOUT
параметры
o Является подсказкой для генерации вызова функции в языке
 В принципе внутри WSDL документа могут идти несколько операций с
одним именем, различающиеся по списку параметров, но BP это
запрещает.
 Шаблоны выполнения операций:
• Request/Response - один input, один output и >=0 fault параметров
• One-Way - один input, нет output и fault. Клиент все-таки ожидает, но
ТОЛЬКО HTTP ответа с кодом и без содержания – на это есть вопрос
• Solicit-response - один output, один input и >=0 fault параметров.
Послает сообщение и ждет ответа. Не поддерживается BP
• Notification - один output, нет input и fault параметров. Послает
сообщение и все. Не поддерживается BP

Связывание - binding
o Общие WSDL не привязанные к SOAP элементы - binding, operation, input,
output, fault. Используются без префикса, так как принадлежат дефолтной схеме
http://schemas.xmlsoap.org/wsdl/
o Привязанные к SOAP элементы, используемые с префиксом - soapbind:binding,
soapbind:operation, soapbind:body, soapbind:fault, принадлежат к
http://schemas.xmlsoap.org/wsdl/soap
o Определяет привязку к интерфейсам протоколов – SOAP/HTTP/MIME, типа –
RPC/Document и стиля кодирования – literal/SOAP. То есть определяет, как
физически будет реализовывать portType определение
o Связывание - binding(documentation?, soapbind:binding, operation*), основные
атрибуты
 name
 type - какой интерфейс описываем
Внутри элементы:
• soapbind:binding – определение для SOAP протокола передачи (всегда
HTTP) и стиля обмена сообщениями. Атрибуты:
o transport = http://schemas.xmlsoap.org/soap/http/ (это не
запрещает использовать HTTPS)
o Style = rpc | document
• Operation(documentation?, soapbind:operation, input*, output*,
fault*) – определение операции
• Атрибуты
o name - ссылающийся на операцию интерфейса,
o Согласно BP набор операций должен соответствовать набору
операций portType
Внутри элементы:
o soapbind:operation – определение операции для SOAP,
атрибуты
 Style – стиль вызова, может переопределить заданный
для интерфейса в целом. BP требует что бы был тот же самый,
что и у связывания. Опциональный элемент
 soapAction – ИД операции, может быть опущен.
Значение будет коррелировать с заголовком soapAction HTTP
пакета с запросом
o input (soapbind:body, soapbind:header?) - входной параметр,
o атрибут name
o атрибут message указывает на используемое в качестве тела
сообщение, опциональный
o output (soapbind:body, soapbind:header?) – выходной
параметр
o атрибут name
o атрибут message указывает на используемое в качестве тела
сообщение, опциональный
o fault (soapbind:fault, soapbind:headerfault?) – исключение
o атрибут name
o Внутри определений операций используются SOAP элементы
o Во всех
 «use» - по BP только literal и оно же по умолчанию
o soapbind:body – определение связывание для параметра
 parts – какие части сообщения используем (если только
используем не все части), опциональный
• Может быть «» - не используем ни одной части из
сообщения
• BP требует, чтобы порядок part в теле был тот же
самый, что и в сообщении
 если style=document, то parts не используется, а в
сообщении должна быть только одна часть использующая
element атрибут
• если style=rpc, то используемые (в частности в
parts) части сообщения должны быть с type атрибутом и не
использовать xsl:nil атрибут. Не используемые – как угодно
основные атрибуты
 encodingStyle – никогда не используется
 namespace
• для rpc-style сообщений определяет URL схемы,
должен соответствовать targetNamespace всего WSDL
документа. В соответствии с BP должен использоваться.
• Для document-style в соответстии с BP
использоваться не должен
o soapbind:fault – определение связывание для сообщения об
ошибки..
 Определяется по одному элементу на исключение,
выбрасываемое методом интерфейса
 Основной атрибут - name – ссылка на соответствующее
сообщение.
 Могут использовать только parts с атрибутом element.
 для rpc-style сообщений атрибут namespace
использоваться не должен
o soapbind:header / soapbind:headerfault – определение
связывание для заголовка, основные атрибуты:
 Основной атрибут - message – QName ссылка на
соответствующее сообщение. Может указывать на то же
сообщение, что и родительская структура input / output
 Может использовать атрибут part для указания одной
части сообщения, используемого как заголовок. Можно
использовать только части с атрибутом element
 В соответствии с ВР использование parts запрещается
 для rpc-style сообщений атрибут namespace
использоваться не должен
 В принципе сообщение может содержать заголовок с
ошибкой и не описанный в headerfault

Определение сервиса
o Корневой элемент Service(documentation?, port*), каждый из port определяет
свой выставляемый сервис
o Service атрибуты:
 Name
o Port (documentation?, soapbind:address) атрибуты:
 Name
 Binding – QName связывания
внутри привязка к конечной точке в виде элемента soapbind:address с
атрибутами:
 Location – URL конечной точки. Согласно BP можно
использовать только HTTP и HTTPS
o Можно одно связывание выставить как несколько разных URL, например в целях
баланса
o Два port элемента могут использовать одно и то же значение Location, но это не
совместимо с BP

Определение WS-I совместимости


o Может вкладываться в wsdl:documentation элемент следующих определений:
 wsdl:port
 wsdl:binding
 wsdl:portType
 wsdl:operation как часть wsdl:portType
o наследование признака идет по принципу основывания описания. То есть
совместимость элемента требует совместимости всех используемых элементов
 wsdl:port требует wsdl:binding
 wsdl:binding требует wsdl:portType
 wsdl:portType требует wsdl:operations
 wsdl:operation требует wsdl:messages, использованными в wsdl:output и
wsdl:input

SOAP 1.1

Общие замечания
o В принципе может ходить через SMTP, FTP и любые другие протоколы, но WS-I
Basic Profile специфицирует только через HTTP
o SOAP/HTTP НЕ гарантирует доставку – наследуется от TCP
o Используются только POST запросы
o Достоинства SOAP
 Формат на основе схем – хорошо расширяем
 HTTP – легко туннелируется
o XML
 заголовок не обязателен, кодировка только UTF-8/16
 базовая схема должна быть SOAP 1.1
 все элементы должны быть полностью квалифицированны через
дефолтную схему или префиксы
o Заголовок, утверждающий совместимость сообщения с BP:
<wsi:Claim conformsTo="http://ws-i.org/profiles/basic/1.0"
xmlns:wsi="http://ws-i.org/schemas/conformanceClaim/" />
o Всегда опциональный, требовать необходимости его обработки нельзя
o Можно объявлять совместимость более чем с одним профилем
o Требования к совместимости сообщения с BP (кроме ниже по тексту)
 Не используется soap:encodingStyle в элементах в soap пространстве
 Не используется soap:encodingStyle в непосредственно дочерних к body
элементах
 При использовании rpc-literal не используется soap:encodingStyle в body
вообще
 Не содержит DTD и PI
 После body никаких дополнительных элементов идти не должно
o Для RPC сообщений тело может содержать только один элемент = один вызов
o SOAP messages are universally supported across different platforms – достоинство
SOAP/HTTP

Обработка сообщения
o В процессе обработки перемещается между отдельными обработчиками – node
o Различаются промежуточные и окончательный адресат
o Каждый обработчик может
 Идентифицируется уникальным URI, который используется в заголовках
 обрабатывать предназначенные ему заголовки, обязательно убирая их из
сообщения после обработки. В принципе может к убранному добавить
информацию и вернуть опять для следующего – например при хранении
лога пройденных узлов в заголовке пакета
 добавлять новые заголовки
 не вправе изменять тело сообщения
 получатель отвечает только за свои действия и не может возбудить
ошибку, если предыдущие получатели не обработали или не убрали
предназначенные им заголовки
o Первое, что производится нодой – обработка предназначенных блоков заголовков
– удаление из сообщения, только потом производится анализ на mustUnderstand
атрибут, затем уже реальная обработка

Формат сообщения
o Схема - http://schemas.xmlsoap.org/soap/envelope/. Если у сообщения схема
другая, то генерируется ошибка
o Корневой элемент – soap:Envelope(soap:header?, soap:body), под ним все
остальное – тело и заголовок.
 Атрибуты
• soap:encodingStyle = http://schemas.xmlsoap.org/soap/encoding/ -
кодировка данных, используемая в документе.
o Не обязательный
o может встретиться также в любом SOAP элементе,
o действует вниз.
o Не совместим с BP
 Может содержать определения пространства имен и дополнительные
атрибуты из этих пространств. Такие дополнительные по отношению к soap
атрибуты должны быть QName
 Может содержать любые вложенные элементы после soap:body, такие
элементы должны быть QName. ВР такие элементы запрещает
o Элементы сообщения могут иметь любые дополнительные атрибуты, если они
квалифицированны префиксом или дефолтным пространством. То же самое
относится к элементам – детям SOAP элементов сообщения
o Перечень заголовков – soap:Header(any*)
 в единственном экземпляре, опциональный элемент. Должен идти первым
в конверте
 содержит любое число дочерних элементов – заголовков, каждый из
которых должен быть QName. Дочерние элементы не могут относиться к
SOAP пространству. Аналогично ниже.
 Атрибуты отдельных заголовков, обращенные к обработчикам:
• soap:actor – ИД обработчика в виде URI, которому предназначен
заголовок и который должен его по идее обработать. Имеются
стандартные ИД:
o http://schemas.xmlsoap.org/soap/actor/next - заголовок
должен быть обработан следующим получателем
o «» - заголовок адресован конечному получателю
• soap:mustUnderstand – признак того, что обработчик,
идентифицируемый по soap:actor, должен обязательно обработать
заголовок
o если не может и «1», то возбудить ошибку
soap:MustUnderstand и не пропускать сообщение дальше –
отправить обратно
o Если не может и «0» - просто убрать заголовок из пакета
o Проверка всех заголовков на возможность обработки
осуществляется перед началом их реальной обработки
o Можно выставить в любом месте SOAP сообщения
• soap:encodingStyle – может использоваться для указания кодировки
содержимого. Не совместим с BP
o Тело – soap:Body(any|fault)
 в единственном экземпляре, обязательный элемент, сразу в конверте или
после заголовка
 дочерние элементы могут, но не обязаны быть QName. WS-I BP 1.0
требует, чтобы все непосредственные дети были QName
 Непосредственныевложенные элементы НЕ могут описываться
encodingStyle. Rpc-literal не могут содержать данного атрибута и ниже
 содержит либо данные запроса, либо информацию об ошибке. И то и
другое нельзя
 изменять содержание тела может только окончательный получатель. Хотя
он и не существует возможноти узнать, было ли оно изменено по пути
 Виды кодировки тела с данными:
• По смыслу содержания – Document / rpc. Первый просто должен
соответствовать заданной для него в WSDL произвольной бизнес
схеме. Второй описывать вызов программной процедуры над
графом объектов, то есть соответствовать схеме, отвечающей
программному интерфейсу
• Схемы задаются как правило в элементе Envelope, но могут и ниже
• По языку разметки – literal / encoded. Первый утверждает, что каждый
фрагмент XML должен быть верифицируем схемой взятый сам по
себе. Второй в целях совместимости нынче уже не используется
o Тело с описанием ошибки
 Возвращаются ли ошибки или нет при возникновении исключений на
сервере зависит от типа вызова. Для One-Way вызовов не возвращаются,
так как нет обратного сообщения
 Виды ошибок - неверного формата сообщения, ошибки версии, проблема с
обработкой заголовка или тела
 Содержит единственный дочерний элемент – soap:Fault(faultcode,
faultstring?, faultactor?, detail?), к нему м.б. только следующие
неквалифицированные дочерние элементы:
• faultcode – код ошибки, в принципе может быть любой,
обязательный элемент, QName с префиксом
• BP определяет только 4 стандартных значения faultcode:
o soap:Client – ошибка формирования сообщения клиентом. То
есть данные сообщения ошибочны или имеют неверный
формат или недостаточно информации, например заголовка. В
этом случае сообщение НЕ высылается повторно
o soap:Server – ошибка обработки сообщения. То есть с
сообщением все ОК, а вот обработать не удалось. В
большинстве случаев сообщение может доставляться
повторно
o soap:VersionMismatch – сообщение принято нормально, но
пространство имен элементов Envelope, Header, Body, и Fault –
не распознано
o soap:MustUnderstand – некоторый заголовок должен быть
обработан (атрибут actor), есть обработчик (атрибут
mustUnderstand), но формат заголовка не распознан
o от этих значений через «.» нотацию могут формироваться
уточняющие. Сейчас не используются
• Согласно BP могут использоваться и другие значения faultcode, если
они QName
• faultstring – сообщение об ошибке.
o Обязательный элемент.
o Может применяться атрибут xml:lang="es" для указания
локализации
• faultactor – ИД обработчика, возвратившего ошибку.
o Если обработчик промежуточный, то обязательный элемент,
если конечный – опциональный
o Обычно содержит URI, но может и IP например – не
специфицированно
• detail – описание ошибки
o Должен присутствовать, если ошибка вызвана обработкой
содержания тела. То есть его наличие означает, что тело
обрабатывали
o Не может быть использован, если ошибка вызвана обработкой
заголовка. В данном случае ошибку надо возвращать тоже
заголовком
o Внутри любой XML, квалифицированный (обязательно
отличный от SOAP-ENC) или неквалифицированный. Его
может и не быть вовсе
o Вложенные элементы могут описываться encodingStyle

SOAP Encoding
o В соответствии с WS-I BP массивы использоваться не могут, не непосредственно,
не наследуясь
o Определяет правила сериализации и десериализации графов объектов,
состоящих из
 Простых типов – string, enumeration, array of bytes
 Сложных типов – array, structure
o Общие принципы:
 Данные представляются как элементы. Атрибуты используются как
описатели структуры или ссылки
 Каждое наименование поля / класса / метода / параметра соответствует
наименованию элемента
 Верхнеуровневые элементы QName, внутренние просто
 Применяются как дети header / body
 Для описания структур данных используется теги из пространства имен enc
= http://shcemas.xmlsoap.org/soap/encoding
 Для описания классов / методов используются теги из бизнес пространств
имен
 Если значение элемента null и схема это допускает используем nil=”true”
 Отличие SOAP-ENC данных от XSD
• Ref – позволяет сослаться из одного элемента на другой по
значению его атрибута «name»
• Href - позволяет сослаться из одного элемента на другой в виде
«#id_value» по значению его атрибута «id»
o Сериализация связанных данных
 Простые одинарные ссылки - снаружи метод или класс, параметры – дети.
QName только внешние элементы – метод или класс. Вложенные классы
или параметры уже просто теги. Значения – внутри родителей.
 Сложные ссылки – отдельно вызов метода, отдельно значение. Параметры
на значения ссылаются через href = “#id”/ id=”id”. QName опять-таки
только внешние элементы – непосредственные дети soapBody
o Динамическая типизация
 Использует пространство имен xsi = http://www.w3.org/2001/XMLSchema-
instance
 В теге xsi:type определяем новый тип, взамен подразумеваемого
o Массивы
 Поддерживаются одно и многоразмерные, с перемерной размерностью
 Тип описывается атрибутом enc:arrayType – обязательный, значение
QName. В нем же указывается размерность массива
 Каждый элемент массива сериализуется как отдельный элемент с
произвольным наименованием наименованием
 Внешний контейнер – enc:Array, в нем enc:arrayType и необходимые
пространства имен
 Внутри
• Для Enc:arrayType=”xsd:long[5]” - внутри 5 штук <enc:long>????
</enc:long >
• Для Enc:arrayType=”xsd:string[2,3]” - внутри 6 штук <item >????
</item >
 Или определение элемента с type=”enc:Array”, а в самом элементе
атрибутом enc:arrayType задаем тип того, что будет внутри
 Поддерживается передача данных массива со смещением -
enc:offset=’[?]’
 Поддерживается передача выделенных элементов - <item
enc:position=’[?]’>????</item >
 Поддерживаются массивы разной размерности
• Снаружи enc:arrayType=”xsd:string[][2]”
• Внутри (дочерние) два массива, каждый с
enc:arrayType=”xsd:string[переменная размерность]”
• Внутри массивов с переменной размерностью – обычные значения
• В принципе внутренние массивы могут лежать отдельно и
привязываться через href / id
Передача поверх HTTP
o Версии протокола – лучше HTTP 1.1, но может использоваться и 1.0 - менее
предпочтительнее
o Используется только POST
o Три обязательных заголовка в пакете:
 Content-Type - в соответствии с BP должен быть «text/xml Content-Type».
Могут использоваться другие значения, например для SOAP with
Attachments - multipart/related, но это не рекомендовано
 Content-Length
 SOAPAction.
• Обязательно в «»
• Его содержание не специфицировано, но не может быть опущено –
минимум «».
• BP требует, чтобы оно соответствовало значению soapAction
атрибута WSDL документа
o В HTTP ответа никакого специального заголовка не требуется
o Используются HTTP коды
 200 – OK, сообщение нормально получено и обработано, то есть в
результате содержится не fault
 202 – Accepted, сообщение было получено и обработано, но ответа нет
вовсе. Используется в «One-Way» вызовах. Не означает, что обработка
сообщения произошла без ошибок
 307 – временный редирект, потребитель может (но не обязан) перейти на
новый адрес
 400 / 404– неправильный формат HTTP пакета или XML документ не well-
formed
 405 – Method Not Allowed, при попытке использовать что-то кроме POST
 415 – Unsupported Media Type, запрос имеет неверный ContentType
 500 – Internal Server Error, когда возвращается в ответ fault
o Куки – могут использовать, но сервис не должен полагаться на то, что
потребитель их поддерживает. То есть должны использоваться как hint

SOAP со вложениями
 В заголовке: Content-Type: Multipart/Related; boundary=MIME_boundary;
type=text/xml; start="<content-id>"
 В теле HTTP пакета отдельные части разделяются:
--MIME_boundary
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: 8bit
Content-ID: <content-id>
 В конце пакета окончание «--MIME_boundary--»
 В элементах ссылки на внедренное сообщение по типу <element
href="cid:< content-id>"/>

Достоинства и недостатки SOAP


o Обеспечивают децентрализованное и распределенное окружен ие
o Нет встроенной безопасности
o В 1.1 стандарте нет дефолтной кодировки для содержимого тела
o Сериализованные объекты теряют связь с источником
 Нет распределенной сборки мусора
 Нельзя создать stateful ссылку на удаленный объект
SOAP 1.1 API – SAAJ 1.2

Общие замечания
o Одинаково оперируется как с простыми SOAP, так и с SwA сообщениями
o Рамочное API – каждый J2EE вендор предоставляет свою реализацию общих
интерфейсов
o Используется как в составе JAX-RPC, так и самостоятельно – простое req/res
взаимодействие поверх HTTP
o Каждый тип соответствует SOAP объекту и порождает из себя дочерние типы
o Основные пакеты
 Javax.xml,soap – все основные класс, самостоятельный пакет
 Javax.xml, messaging – дополнительные провайдеры для работы с
сообщениями, промежуточной обработки, асинхронного вызова и т.д.
Зависит от первого в части создания и манипуляции сообщениями
o В качестве вложений передается все, что не XML.
 Так как не часть XML документа сообщения, то не может быть подписано в
соответствии с общим подходом
 Content-type целого сообщения меняется в момент добавления первого
вложения
 Добавляется изо всего – string / Source / DataHandler
o SAAJ развелось из JAXM

Основные части сообщения


o MIME сообщение – SOAPMessage
SOAP часть – SOAPPart
• Конверт – SOAPEnvelope
o Заголовок – SOAPHeader
 Верхнее уровневый QName элемент –
SOAPHeaderElement
• Бизнес элемент – SOAPElement
o Text
o Тело – SOAPBody
 Верхнее уровневый QName элемент –
SOAPBodyElement
• Бизнес элемент – SOAPElement
o Text
MIME вложение – AttachmentPArt
• Для application/xml вложений используется javax.xml.transfor.Source

Основные типы данных


o Name – представление QName
 Создается за счет
• SOAPEnvelope.createName(name, prefix,uri)
• SOAPFactory.createName(name, prefix,uri)
 Get свойства – localName, prefix, QualifiedName, URI
o SOAPFactory – фабрика созданию SOAP элементов
 Создаются как createElement(Name | (localName [, prefix, uri]))
 Получается как newInstance()
o MessageFactory – фабрика сообщений
 Получается как MessageFactory.newInstance()
 Создает
• пустое сообщение, содержит пустой заголовок и пустое тело
• сообщение из
o набора MIME заголовков MimeHeaders. Заголовки
добавляются как addHeader(name, value). Важнейший –
Content-Type
o InputStream, поставляющего полное XML представление
сообщения.
• Элементы сообщения в том случае, когда мы не имеем доступа к
сообщению в целом или к его конверту
o SOAPConnectionFactory – фабрика для создания HTTP соединений для
простейшего Request / Response вызова. Только два метода - newInstance() и
createConnection()
o SOAPConnection – HTTP соединение
 предоставляет метод SOAPMessage call(SOAPMessage, Object to) для
отправки сообщения по заданному URL с использованием POST запроса
 должно закрываться через close()
o SOAPMessage – сообщение
 Создается фабрикой MessageFactory
 Получение основных частей сообщения – getSOAP[Body | Header | Part]
 Выгрузка в поток - writeTo(OutputStream)
 Работа с вложениями
o SOAPElement – основа для всего остального и представление элементов, не
относящихся к SOAP схеме
 Расширяет Element из DOM2
 Свойства – encodingStyle, elementName,
 Создание
• SOAPElement.addChildElement( Name | localName [prefix [URI]])
• SOAPFactory.createElement(Name | localName [prefix , URI])
• Методов для создания отдельных элементов нет: создаются
фабрикой или конвертом, в родителей мы их только добавляем
 Работа с атрибутами – addAttribute(name, value), getAllAttributes(),
getAttributeValue(name), removeAttribute(name)
 Работа с дочерними элементами – addChildElement(Element),
getChildElements(), getChildElements(name), addTextNode(text),
removeContents()
 Работа с пространствами имен – addNamespaceDeclaration(prefix,uri),
getNamespacePrefixes(), getNamespaceURI(prefix),
getVisibleNamespacePrefixes(),removeNamespaceDeclaration(prefix)
 Унаследованные от Node
• detachNode – удаление данного элемента из родителя. Часто
вызывается на SOAPHeader, если заголовок в только что созданном
сообщении не нужен
• getParentElement
• [get|set]Value
• recycleNode – удаление со сборкой мусора, сообщает
имплементации
o SOAPEnvelope – конверт, наследник SOAPElement, добавляется
 Add/get Body/Header
 Name createName(localName, [prefix, uri])
o SOAPHeader – наследник SOAPElement, представление заголовка сообщения.
Добавляет специфику создания и выборки отдельных заголовков:
 addHeaderElement(Name) – создание заголовка SOAPHeaderElement
 examineAllHeaderElements(), examineHeaderElements(actor),
examineMustUnderstandHeaderElements(actor) – получение итератора с
заголовками, все или с отбором
 extractAllHeaderElements, extractHeaderElements (actor) – получение
итератора с удалением. В обязательном порядке требуется от
промежуточных получателей сообщения.
o SOAPHeaderElement – отдельный заголовок, наследник SOAPElement,
добавляется работа со свойствами – actor и mustUnderstand
o SOAPBody – тело сообщения, наследник SOAPElement, добавляет:
 Создание элементов тела SOAPBodyElement
• addBodyElement(Name) – добавляется очередной элемент
• addDocument(Document) – единственный корневой элемент тела
 Создание ошибки SOAPFault addFault([faultCode, faultString [,locale]])
 Получение ошибки – SOAPFault getFault()
 Выяснение есть ли ошибка – Boolean hasFault()
 В экзамене есть вопрос, про то что она present SOAP message header block.
Не непосредственно, но наверное да, предоставляет
o SOAPBodyElement - элемент тела, наследник SOAPElement, ничего не
добавляется
o SOAPFault – описание ошибки, наследник SOAPBodyElement, добавляется
 Работа с детализацией – [add|get]Detail()
 Работа с автором – [get|set]faultActor
 Работа с кодом – [get | set] faultCode(String | Name)
 Работа с сообщениями - – [get | set] faultString[Locale](String [,Locale])
o Detail – детализация ошибки, наследник SOAPFaultElement (наследник
SOAPElement ничего не добавляет), добавляется
 Создание DetailEntry (наследник SOAPElement ничего не добавляет) - add
DetailEntry(Name)
 Получение DetailEntry – Iterator getDetailEntries()
o SOAPException – возбуждается самим движком, не имеет отношение к ошибке в
сообщении

Использование – общая работа с сообщениями


o Создание фабрики сообщений
MessageFactory msgFactory = MessageFactory.newInstance();
o Создание фабрики SOAP элементов
SOAPFactory soapFactory = SOAPFactory.newInstance();
o Создание пустого сообщения
SOAPMessage message = msgFactory.createMessage();
o Загрузка сообщение из файла
MimeHeaders mimeHeaders = new MimeHeaders();
mimeHeaders.addHeader("Content-Type","text/xml; charset=UTF-8");
FileInputStream file = new FileInputStream("soap.xml");
SOAPMessage requestMsg = msgFactory.createMessage(mimeHeaders, file);
o Отправка и получение результата
 endpoint определяется как URL или String
 сервис должен поддерживать POST обращение и возвращать корректное
сообщение в ответ
 клиент на время выполнение запроса блокируется

SOAPConnectionFactory conFactry = SOAPConnectionFactory.newInstance();


SOAPConnection connection = conFactry.createConnection();
URL url = new URL(args[0]);
SOAPMessage replyMsg =connection.call(requestMsg, url);
o Загрузка SOAPPart из документа
SOAPPart soapPart = message.getSoapPart();
soapPart.setContent(domSource)
Использование – работа с сообщением
o Получение тела сообщения
SOAPBody body = message.getSOAPBody();
o Создание UUID
String uuid = new java.rmi.dgc.VMID().toString();
o Создание имени
Name getBookPrice_Name = soapFactory.createName("getBookPrice","mh",
"http://www...");
o Работа с телом
Name isbnName = soapFactory.createName("isbn");
SOAPBody body = message.getSOAPBody();
SOAPBodyElement getBookPrice_Element = body.addBodyElement(isbnName);
Iterator iter = body.getChildElements([name]);
o Формирование тела (или чего другого) из DOM2 элемента – обязательно вначале
импортировать DOM фрагмент внутрь нового документа, а только потом уже его
добавлять
Node elementCopy = soapPart.importNode(xmlDoc.getDocumentElement(), true);
soapBody.appendChild(elementCopy);
o Формирование тела за счет DOM документа
soapBody(addDocument);

Использование – работа с загловками


o Получение заголовка
SOAPElement header = message.getSOAPHeader();
o Удаление заголовка
header.detachNode();
header.recycleNode();
o Добавление элемента в заголовок
SOAPHeaderElement msgIdHeader = (SOAPHeaderElement)
header.addChildElement("message-id","mi", "http://www...");
msgIdHeader.addTextNode(uuid);
String uuidStr = msgIdHeader.getValue();
msgId.setActor("http://www.Monson-Haefel.com/logger");
msgId.setMustUnderstand(false);
SOAPElement newNode = msgIdHeader.addChildElement("subnode");
o Работа с атрибутами
newNode.addAttribute(smthName,”….”)
Iterator iter = newNode.getAllAttribute();
Name attName = (Name)iter.next()
String attValue = newNode.getAttributeValue(attName)
newNode.removeAttribute(attName)
o Получение заголовков (с удаление или без)
Iterator iter = header.extractHeaderElements(headerName)
Iterator iter = header.examineHeaderElements(headerName)

Использование – работа с ошибками


o Создание ошибки
SOAPFault fault = body.addFault();
fault.setFaultCode("soap:Client");
fault.setFaultString("The ISBN contains an invalid character(s)");
fault.setFaultActor("http://www.Monson-Haefel.org/BookQuote_WebService");
o Дополнение ошибки детализацией
Detail detail = fault.addDetail();
DetailEntry detailEntry = detail.addDetailEntry(errorName);
SOAPElement offendingValue = detailEntry.addChildElement("offending-value");
o Получение и перебор
If(body.hasFault()) {
SOAPFault fault = body.getFault()
Detail detail = fault.getDetail()
Iterator iter = detail.getDetailEntries();
}

Использование – работа с вложениями


o Добавление вложения
AttachmentPart attachment = message.createAttachmentPart();
Attachment.setContent(obj, contentTypeString)
Attachment.setContentId(IdString)
o Добавление вложения из DataHandler, которые создаются на основе DataSource
двух видов - FileDataSource / URLDataSource
DataHandler dh = new DataHandler(new FileDataSource(file));
AttachmentPart attachment = message.createAttachmentPart(dh);
message.addAttachmentPart(attachment);
o Добавление ссылки на вложение как атрибута
SOAPElement source = bodyElement.addChildElement("source",""),
source.addAttribute(envelope.createName("href"), "cid:" +
attachment.getContentId());
o Получение по типу
MimeHeaders headers = new MimeHeaders();
Headers.addHeader(‘Content-Id’,’…’)
Iterator iter = message.getAttachments([headers]);

JAX-RPC 1.1 – общее

Java => WSDL


o Приемущества
 Можно быстро вывесить то, что уже есть
 Не требует знания WSDL или XML
 Легчайший способ вывесить перегруженные операции – на это есть вопрос
o Недостатки
 Сгенерированная схема будет содержать типы данных из приложения, а не
стандартные
 Сгенерированный интерфейс может не основывать на простых DTO
объектах и заключать в себе бизнес логику
 Сгенерированная схема включена в WSDL и не может быть повторно
использована
 Нельзя сервера и клиента разрабатывать в параллель: сначала серверный
скелетон и DTO, а затем клиентский стаб и DTO
 Трудно поддерживать вносимые в интерфейс изменения
 Namespaces в WSDL генерятся из наименований пакетов. При
рефакторинге невозможно сохранить совместимость

WSDL => java


o Недостаток – ограниченная поддержка средствами разработки
o Разделы WSDL
 types, message, portType – абстрактное определение
 binding, service – определение уже конкретной реализации
o portType один в один маппится на Java интерфейс endpoint.
 Используются только One-Way и Request/Response вызовы.
 Solicit/Response и Notification НЕ поддерживаются
 Не позволительны Remote ссылки
 Все параметры передаются по значению
o Маппинг между Java пакетами и пространством имен – в JAX-RPC
конфигурационном файле
o Маппинг имен
 portType имя => наименование интерфейса
 operation имя => наименование метода
• можно несколько операций с одним именем, но различающихся по
набору параметров. НЕ совместимо с BP
• Если декларирует только input параметры, то One-Way операция,
соответственно:
o Метод возвращает null
o Возвращается только HTTP код (200/500), который может
представляется как абстрактное RemoteException
 part имя => наименование параметра
• несколько part => несколько параметров
• если output part в возвращаемом сообщении одна, то она идет в
return
• если много – все идет в параметры, OUT и INOUT parts фигурируют
как javax.xml.rpc.holders.XXXHolder типы

XML Schema => java


o Для встроенных типов
 Элементарные, например byte
• xsd:byte => byte / soapenc:byte => Byte
• если есть nillable=true => java.lang.Byte
• если OUT/INOUT параметр => ByteHolder
• Если nillable=true и OUT/INOUT параметр => ByteWrapperHolder
• Char – не поддерживется, считается, что это String
 Для string, DateTime, integer, decimal – только типы и холдеры вне
зависимости от nillable
 xsd:Qname => java.xml.namespace.QName и QNameHolder
 xsd:base64Binary и xsd:hexBinary => byte[] и ByteArrayHolder
 xsd:any => SOAPElement
o Сложный тип => класс с тем же именем, элементы => private свойства и get/set
методы. Для класса должно выполняться:
 Типы элементов должны поддерживаться
 Публичный конструктор без параметров
 НЕ реализует прямо или опосредованно java.rmi.Remote
 Может реализовывать любый другие интерфейсы
 Может содержать private / protected / static / transient свойства и методы
o Если для элемента maxOccurs>0, то возвращается []. Другие варианты не
поддерживаются и игнорируются
o Для перечислений создаются классы с public static final членами
o Если схема не преобразуется в класс бина, то используется тип данных
SOAPElement. Например, для типа group

Holders типы
o Если part упоминается в output части, то она считается INOUT или OUT
параметром и оформляется как Holder
o Доступ к значению – через public переменную value
o Если есть одна part, которая не упомянута в input, упомянута в output и не
фигурирует в parameterOrder – это return выражение
o parameterOrder – опциональный, если не упомянут
 параметры идут в порядке определения, сначала input, затем output
 INOUT идут в порядке определенном в input
o Типовой holder, интерфейс Holder – знаковый, ничего не определяет
public class IntHolder extends javax.xml.rpc.holders.Holder {
public int value;
public IntHolder(){}
public IntHolder(int myint){ value = myint; }
}
o Если тип данных не стандартный, то генерируется специальный Holder класс для
его поддержки. Генерируются только для типов, которые фигурируют как части /
аргументы
o Если в OUT / INOUT фигурирует массив (sequence), то для него тоже создается
холдер

Faults / Exceptions типы


o Stub использует RemoteException для отображения
 Сетевые проблемы
 TCP/IP проблемы
 HTTP проблемы
 Отображения стандартных Fault кодов – клиент, сервер …
o Кроме необходимого RemoteException endpoint методы могу декларировать
бизнес исключения, соотносимые с fault сообщениями
o Методы могут возбуждать ТОЛЬКО прикладные исключения и никогда не должны
возбуждать RemoteException
o Fault => исключение, наследуемое от Exception. Его ЕДИНСТВЕННАЯ часть
 фигурирует в конструкторе
 private член
 get метод
o Если тип части Fault сложный, то отдельные его элементы идут отдельно в
конструктор, члены класс и get методы

JAX-RPC 1.1 – client API

Общие замечания
o Используется RPC / Document Literal кодирование
o Основные типы
 Unmanaged – неуправляемые, изнутри обычного J2SE
 J2EE container-managed
o Исходящие SOAP сообщения не валидируются
o Основные технологии
 Статический стаб – генерится интерфейс из WSDL и stub.
• Изменения не предполагаются
• Стаб класс реализует Stub и SEI
• Можно переконфигурировать точку доступа и логин / пароль
• Единственный опциональный параметр конфигурации – адрес точки
доступа, так как он берется из WSDL файла
• Единственный, который поддерживается J2ME как «subset of JAX-
RPC»
 Динамический прокси - генерится интерфейс из WSDL, stub создается
динамически
• Можно поменять сервис в рамках одного WSDL документа
• Стаб эмулируется, реализует Service
•Необходим доступ к WSDL документа и указание используемого
сервиса
• Application provides WSDL at runtime
 Полностью динамический (DII) – все происходит во время выполнения
• WSDL документ не нужен вовсе
• Сервис, форматы и типы указываются в процессе выполнения
запроса
• Единственный, который поддерживает OneWays вызовы
o Работа клиента изолирована от подробностей сетевого протокола, транспорта,
XML формата и т.д.
o BASIC авторизация:
 Javax.xml.rpc.security.auth.username
 Javax.xml.rpc.security.auth.password

Реализация
o Пакет javax.xml.rpc
o Основная точка доступа – ServiceFactory и Service
 Service предоставляется как статический стаб или динамический прокси
o В J2SE коде доступ
Service service = ServiceFactory.newInstance().createService(
newURL(serviceUrl), new QName(namespaceName, serviceName))
o В J2EE коде доступ
Service service = ic.lookup(“java:comp/env/service/HelloService”)
o Не обязательно предоставляются провайдером следующие методы Service
 getHandlerRegistry()
 getTypeMappingRegistry()

на основе статического stub


o Из WSDL создаются JAX-RPC компилятором
 portType=> интерфейс.
• Производится для всех портов в WSDL документе
• Для oneWay вызова методы возвращают null
 operation => функцию интерфейса, возбуждающую
java.rmi.RemoteException
 port / binding => стаб, реализующий интерфейс.
• Имплементирует также javax.xml.rpc.Stub
• При помощи свойств устанавливаются опции – статические члены от
javax.xml.rpc.Stub
o ENDPOINT_ADDRESS_PROPERTY
o PASSWORD_PROPERTY
o USERNAME_PROPERTY
o SESSION_MAINTAIN_PROPERTY
• Ориентирован на определенный протокол и транспорт
• На другой сервис переключен быть не может – на это есть вопрос
 service => фабрика, создающая стаб.
• Наименование фабрики на основе имени service
• Получение стаба через get метод, возбуждающий
javax.xml.rpc.ServiceException.
• Наименование метода, стаба и интерфейса на основе имени
portType
• Созданный стаб жестко завязан на протокол и адрес, указанные в
WSDL.
• Фабрика имплементирует javax.xml.rpc.Service. Данный интерфейс
также предоставляет методы для остальных типов клиентов.
• Использование фабрики:
o для J2EE клиентов подвешивается в JNDI контексте в ejb-
jar.xml или web.xml файле

<service-ref xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote" >


<service-ref-name>service/BookQuoteService</service-ref-name>
<service-interface>com.jwsbook.jaxrpc.BookQuoteService</service-interface>
<wsdl-file>BookQuote.wsdl</wsdl-file>
<jaxrpc-mapping-file>META-INF/mapping.xml</jaxrpc-mapping-file>
<service-qname>mh:BookQuoteService</service-qname>
</service-ref>

o Для обычных получается через

// в мультипоточном окружении
SmthService service = ServiceFactory.loadService(SpecificServiceClass.class)
// в однопоточном окружении
SmthService service = new SpecificServiceImplClass()

SmthPort port = service.getSmthPort()


SomResult res = port.doBusinessOperation(…)

o Атрибуты вызовов
 примитивы, их обертки, сложные классы
 holder types – для поддержки OUT и INOUT параметров

на основе динамического proxy


• Интерфейс создается статически.
• Фабрика подвешивается в JNDI или создается на месте
Service service = ic.lookup(“java:comp/env/service/HelloService”)
или
Service service = ServiceFactory.newInstance().createService(
newURL(serviceUrl), new QName(namespaceName, serviceName))

• Сам стаб создается динамически в момент вызова через


java.lang.reflect.Proxy. В принципе создаваемые стабы могут кэшироваться.
Выгода не очень понятна.
• какой port / binding использовать (если есть выбор) задается в самом
вызове:

// с использованием jax-rpc маппинга


Interface port = (Interface)service.getPort(Interface.class);
// без использования маппинга
Interface port = (Interface)service.getPort(QName portName,
Interface.class);

Можно задать в дескрипторе mapping.xml через <wsdl-binding>, тогда


наименование порта при получении можно не указывать:

<java-wsdl-mapping
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote"...>
...
<service-endpoint-interface-mapping>
<service-endpoint-interface>com.jwsbook.jaxrpc.BookQuote
</service-endpoint-interface>
<wsdl-port-type>mh:BookQuote</wsdl-port-type>
<wsdl-binding>mh:BookQuote_LiteralBinding</wsdl-binding>
...
</service-endpoint-interface-mapping>

</java-wsdl-mapping>

полностью динамический
• Может использоваться
o с WSDL документом (требование совместимости с BP), тогда
фабрика сервиса создается на его основе и service-ref элемента дескриптора и
подвешивается в JNDI контексте
o Без него – выходит за рамки экзамена. При нем надо
дополнительно определять параметры вызова, типы параметров и returnType,
точку вызова
• Главная особенность – нет бизнес интерфейса. Все динамически
задается во время вызова – аналог reflection
• Используется когда
o Сигнатура вызова или наименование сервиса заранее не известны
o Необходимо динамическое обращение, например на основе информации из UDDI
• Вызов собирается по частям:
Service service = (Service)
jndiContext.lookup("java:comp/env/service/Service");
Или
Service service = ServiceFactory.newInstance().createService(
new QName(namespaceName, serviceName))

QName port = new QName("http://...","Port");


QName operation = new QName("http://..."," Operation ");
Call callObject = service.createCall(port, operation);
Object [] parameters = new Object[1];
parameters[0] = …;
ResType result = (ResType) callObject.invoke( parameters );
• Множественные OUT/INOUT параметра обслуживаются за счет List
Call.getOutputValues()
• В случае One-Way вызова используется
call.invokeOneWay(inputParams);
• Стандартные наименования схем для элементов -
javax.xml.rpc.NamespaceConstants
• Стандартные типы данных - javax.xml.rpc.encoding.XMLType
• Вызов возбуждает RemoteException, бизнес-значимые исключения
вызываться не могут – идут через Fault фрагмент полученного сообщения

Структура service-ref описателя для J2EE


• Синтаксис – service-ref(service-ref-name, service-interface, wsdl-file,
jaxrpc-mapping-file, service-qname, port-conponent-ref, handler*)
• service-ref-name – имя в JNDI контексте, помещается в
java:comp/env/
• service-interface – полное имя интерфейса компонента,
помещаемого в JNDI контекст.
o Расширяет javax.xml.rpc.Service
o Если используется динамический proxy или полностью
динамический вызов, то можно указать родительский интерфейс
• Wsdl-file – расположение используемого wsdl файла. Должен быть
расположен в том же самом архиве, что и клиент. Не допускается расположение в
дочерних архивах
• Service-qname – полное имя сервиса внутри wsdl файла
• Jaxprpc-mapping-file – расположение файла, который определяет
реализацию используемых типов данных на стороне java
• Port-component-ref (service-endpoint-interface, port-component-
link) – используется для динамического прокси для определения того, какой именно
порт должен использовать для реализации вызова Service.getPort(Class)
o service-endpoint-interface – запрашиваемый интерфейс
o port-component-link – наименование сервлета или EJB.
o Наименование EJB может указывать на EJB в другом архиве
внутри данного EAR - ../ejb/BookQuote.jar#BookQuoteJSE. Путь указывается
относительно архива, содержащего описатель. После «#» указывается ИД
компонента в соответствующем ejb-jar.xml файле
• Handler – описание подвешенного обработчика сообщений

JAX-RPC 1.1 – endpoint API

Общие замечания
o Используется RPC / Document Literal кодирование
o Server API используется в контейнере, то что выставляется как сервис – endpoint
o Исходящие SOAP сообщения не валидируются
o Просто классы (POJO) выставляются через обертку из сервлетов, поставляемых
вендором - JSE модель
o Можно выставлять stateless EJB если необходимо
 использование транзакций
 декларативно определяемой безопасности
 управление нитями со стороны контейнера
o Выставляемый интерфейс – service endpoint interface (SEI)
 должен наследоваться от java.rmi.Remote.
 методы возбуждают java.rmi.RemoteException
 параметры методов должны быть совместимы и сериализуемы при помощи
XML
 для OUT/INOUT параметров используются Holder классы
 константы в интерфейсе использоваться не могут
o Обязательные файлы:
 /WEB-INF/wsdl/*.wsdl – общее описание оконечной точки.
• Должно присутствовать обязательно.
• В время выполнения доступны клиентам как /wsdl/*.wsdl.
• Импортируемые XSD файлы должны располагаться в META-INF
директории или глубже.
 /WEB-INF/webservice.xml – маппинг реализации на WSDL описание (JAX-
RPC mapping file)
• соотносит реализацию и port определение
• позволяет производить независимое наименование сущностей
 /WEB-INF/web.xml – для JSE, определяет сервлеты как оконечные точки и
все, что необходимо для них. Включает дополнительные секции
 ejb-jar.xml – для J2EE, определяет stateless EJB как оконечные точки и все,
что необходимо для них
 /WEB-INF/*.map – mapping файл, определяющий пакеты для генерируемого
кода, а также отображение сложных XSD типов в Java классы
o Принципы разработки:
 Интерфейс => WSDL файл. Невозможно создать автоматически – binding и
service элементы не выводимы из интерфейса
 WSDL => интерфейс
o Предоставление общего сервиса для развертывания веб сервисов –
опциональная операция
o Webservices.xml
 в числе прочего включают SEI и servlet mapping
 в процессе развертывания могут модифицироваться элементы handler,
description и soap-header
o первыми входящие SOAP сообщения обрабатывают «container service»
o последними уходящие клиентские SOAP сообщения обрабатывают handler-ы

на основе сервлетов - JSE


o Multi-thread access consideration is used to design an EJB service end point
o Реализация – обычные POJO классы
 Либо реализуют SEI как «implements»
 Либо просто реализуют все методы SEI, без использования «implements»
 Сами никогда RemoteException не возбуждают, это за них делает скелетон
 Используется пул реализаций с примитивным ЖЦ для каждой –
ServiceLifecycle (Сервисы на основе EJB имплементировать данный
интерфейс не могут)
 Могут реализовывать SingleThreadModel, если требуется однопоточность
выполнения
 Не должны быть final и определять finalize метод
o Реализацию + описатели помещаем в контейнеры, поставляемый вендором
сервлет на основе реализации предоставляет SOAP поверх HTTP, получение и
отправку сообщений
 В web.xml
• определение сервлета
o servlet-class указывает на класс реализации, хотя он и не
имплементирует HttpServlet и не реализует каких-либо его
методов
• маппинг сервлета на URL
o использование «*» запрещено
o для оконечной точки может быть определен только один URL
• аутентификация – только через BASIC и CLIENT-CERT
• для сервлета можно определить параметры, но внутри реализации
сервиса до них невозможно добраться
• rus-as/role-name определяет роль, с которой сервис будет стучаться к
остальным ресурсам контейнера
 В webservice.xml – связка описания сервиса с наименованием сервлета
через service-impl-bean/servlet-link элемент
o Имеют доступ ко всем объектам контейнера через JNDI контекст
 индивидуальный и read only для каждого сервлета и endpoint
 Стандартное место для сервисов - java:comp/env/services
 Видит только те ресурса контейнера, которые описаны в web.xml через
resource-ref, ebv-entry, ejb-ref, ejb-local-ref и т.д.
o Получение доступа к контексту
 Реализуется javax.xml.rpc.server.ServiceLifecyle
• Void init(Object context) throws ServiceException – для каждой
реализации только раз. На это есть вопрос.
• полученный контекст обязательно должен быть приведен
• void destroy()
 context приводится к ServletEndpointContext, через который доступны все
сущности контейнера
• Principal getUserPrincipal();
• boolean isUserInRole(String role);
• MessageContext getMessageContext() – на самом деле это
SoapMessageContext
• HttpSession getHttpSession() throws JAXRPCException –
единственный метод с исключением
• ServletContext getServletContext();
o Работа с сессиями:
 JAXRPCException – если используется не HTTP транспорт
 По умолчанию сессия не открывается
 Инициируется сервером
 Клиент должен едкларировать поддержку сессий как свойство
javax.xml.rpc.session как Boolean.TRUE в свойствах stub (_setProperty)/call
(setProperty), по умолчанию False
 Сервис не должен полагаться на то, что клиенту доступны HTTP сессии
 Параметры задаются в web.xml в минутах, <=0 – бесконечная сессия
 Поддержка через куки / перезаписывание URL / SSL
o Работа с сырым сообщением – через MessageContext
o Principal – может использоваться для авторизации доступа к другим ресурсами /
EJB в зависимости от атрибутов run-as и res-auth дескриптора

на основе EJB
o Только stateless EJB
o Интерфейс веб сервиса - SEI
 расширяет только java.rmi.Remote
 методы возбуждают RemoteException
 НЕ требуется расширять EJBObject или EJBLocalObject
 НЕ нужен Home интерфейс, так как бины будут создаваться контейнером
 SEI прописывается в ejb-jar.xml в session/service-endpoint
 В webservice.xml – связка описания сервиса с наименованием EJB через
service-impl-bean/ejb-link элемент
o Реализация сервиса
 Наследуется от javax.ejb.SessionBean
 Методы бина не должны сами декларировать и возбуждать
java.rmi.RemoteException
o Основная причина – работа с распределенными транзакциями:
 Транзакция представляется как javax.transaction.UserTransaction
 Получается из контейнера на основе JNDI
 Основные методы – begin / commit / rollback
 Типовой прием использования – чтение БД и отсылка сообщения в одной
транзакции
 Как правило, все-таки используют декларативное определение транзакций
в дескрипторе, а не ручное управление
o Из Stateless можно использовать CMB / BMP / MDB бины. Можно statefull, но это
плохой стиль
o Бины и описатели помещаем в контейнер, остальное он берет на себя.
o Декларативное определение транзакций в ejb-jar.xml
• Запрещены - Mandatory / Requires, так как нет обще признанных
протоколов для распространения транзакции между клиентом и сервером
• Required / RequiresNew - начинает новую
• Supports / Never / NotSupported – вовсе без транзакций
• Синтаксис - container-transaction(method(ejb-name,method-name)
+, trans-attribute)
o В method-name можно употреблять «*»
• Пример:
<ejb-jar ...>
...
<container-transaction>
<method>
<ejb-name>BookQuoteEJB</ejb-name>
<method-name>getBookPrice</method-name>
</method>
<trans-attribute>RequiresNew</trans-attribute>
</container-transaction>
...
</ejb-jar>
o Декларативное определение доступа в ejb-jar.xml
• Синтаксис – method-permission((role-name*|
unchecked),method(ejb-name,method-name)+)
• В method-name можно употреблять «*»
• Unchecked – перед доступом к оконечной точки проверка не
выполняется
• Пример
<ejb-jar >
<method-permission>
</unchecked>
или
<role-name>MHSalesperson</role-name>

<method>
<ejb-name>BookQuoteEJB</ejb-name>
<method-name>getBookPrice</method-name>
</method>
</method-permission>
</ejb-jar>
 Безопасность доступа к ресурсам контейнера
 Либо используется роль, определенная в run-as, либо данные
вызывающего пользователя
 Пример:
<ejb-jar><enterprise-beans><session>
<ejb-name>BookQuoteEJB</ejb-name>
...
<security-identity>
<user-caller-identity/>
или
<run-as><role-name>Administrator</role-name></run-
as>
</security-identity>
...
</ session ></enterprise-beans></ejb-jar>

Структура webservice.xml дескриптора


o Обязательный файл – описание реализации конечных точек конкретными JSE или
EJB моделями
o Определение пространства имен в корневом элементе
 xmlns=http://java.sun.com/xml/ns/j2ee
 xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
 xsi:schemaLocation=http://java.sun.com/xml/ns/j2ee
http://www.ibm.com/webservices/xsd/j2ee_web_services_1_1.xsd
 xmlns:xxx="URL бизнес схемы "
o Корень – webservice(webservice-description*)
o Описание сервиса - webservice-description(webservice-description-name, wsdl-
file, jaxrpc-mapping, port-component*)
 Определяет коллекцию оконечных JSE/EJB в одном WSDL. Если wsdl
файлов несколько – для каждого свой дескриптор
 Port-component (port-component-name, wsdl-port, service-endpoint-
interface, service-impl-bean) – маппинг реализующего JSE/EJB компонента
на порт в WSDL документе
• port-component-name – наименование endpoint, уникально в рамках
файла
• wsdl-port – QName порта в WSDL файле
o для JSE port/binding используются для генерации сервлета
o для J2EE – для генерации скелетона, ориентированного на
EJB
• service-endpoint-interface – интерфейс сервиса, реализуемого
endpoint. Должен совпадать с определением service-endpoint в ejb-
jar.xml
• service-impl-bean(ejb-link | servlet-link) – привязка к реализации
конечной точки
o ejb-link – ИД EJB в session-bean элементе ejb-jar.xml
o servlet-link – ИД сервлета в Servlet-name элементе web.xml

Структура mapping.xml файла


o 1:1 соотносится с WSDL файлом
o Не имеет стандартного наименования
o Может быть
 легковесным (lightweght) – определять только наименование пакета для
генерации кода
 полноценным (heavyweight) – полностью мапить XSD типы данных и java
структуры
o Пространства имен от корня в обоих случаях:
 xmlns=http://java.sun.com/xml/ns/j2ee - основное
 xmlns:mh=http://www.Monson-Haefel.com/jwsbook/BookQuote – бизнес
пространство, в случае легковесного не нужна
 xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance – загрузка схемам
 xmlns:xsd=http://www.w3.org/2001/XMLSchema – работа со схемами, для
легковесного не нужно
 xsi:schemaLocation=http://java.sun.com/xml/ns/j2ee
http://www.ibm.com/webservices/xsd/j2ee_jaxrpc_mapping_1_1.xsd -
расположение основного пространства
o Легковесный
 Условие применимости:
• Binding стиль rpc - style="rpc"
• Кодирование - SOAP 1.1 для всех сообщений и ошибок
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/")
• Только один Service элемент с одним port элементом
 Соответственно не совместим с BP
 Пример
<?xml version='1.0' encoding='UTF-8' ?>
<java-wsdl-mapping
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

http://www.ibm.com/webservices/xsd/j2ee_jaxrpc_mapping_1_1.xsd"
version="1.1">
<package-mapping>
<package-type>com.jwsbook.jaxrpc</package-type>
<namespaceURI>http://www….</namespaceURI>
</package-mapping>
</java-wsdl-mapping>
o Полноценный
 НЕТ – error-mapping и method-mapping
 Определяет маппинг между
• XML сложными типами и java классами
• Fault сообщениями и java исключениями
• WSDL portType и java endpoint интерфейсами
• WSDL service и java service интерфейсами
 Корень – java-wsdl-mapping(package-mapping*, java-xml-type-mapping*,
exception-mapping*, service-interface-mapping*, service-endpoint-
interface-mapping*)
• package-mapping (package-type, namespace-uri) – маппинг каждой
схемы в WSDL документе на наименование пакета, в котором будут
генериться артефакты, соответствующие этой схеме
o package-type – наименование пакета
o namespace-uri – uri схемы данных
• java-xml-type-mapping(class-type, root-type-qname, qname-scope,
variable-mapping*) – маппинг XML типа данных на Java бин
o необходимо, если параметры сообщений не примитивные
типы
o variable-mapping(java-variable-name, xml-element-name) –
определение маппинга вложенного элемента данных на
переменную класса
• exception-mapping – аналогичное определение структуры данных
исключения
• service-interface-mapping(service-interface, wsdl-service-name,
port-mapping*) – определение маппинга между service в WSDL и
интерфейсом сервиса
o port-mapping(port-name, java-port-name) – определение
между port в WSDL и прикладным интерфейсом
 port-name – наименование port в WSDL, соответственно
связка с прикладным интерфейсом
 java-port-name – определение наименования
getPortName() метода сервиса. Возвращаемый тип –
определенный выше прикладной интерфейс
• service-endpoint-interface-mapping(service-endpoint-interface,
wsdl-port-type, wsdl-binding, service-endpoint-method-mapping*)
o маппит JAX_RPC endpoint интерфейс на конкретные portType и
binding
o маппит JAX_RPC endpoint методы на конкретные operation и
message part
o помогает JAX-RPC компилятору генерить стабы и интерфейсы
для endpoint
o service-endpoint-method-mapping(java-method-name, wsdl-
operation, method-param-parts-mapping*, wsdl-return-value-
mapping)
 method-param-parts-mapping(param-position, param-
type, wsdl-message-mapping)
• wsdl-message-mapping(wsdl-message, wsdl-
message-part-name, parameter-mode)
 wsdl-return-value-mapping(method-return-value, wsdl-
message, wsdl-message-part-name)
• Элементов «error-mapping» и «method-mapping» - НЕТ

JAX-RPC 1.1 – обработчики сообщений

Общие замечания
o Могут быть развернуты как на клиенте, так и на сервере.
o Служат интерцептором интерфейса сервиса, то есть конфигурируются
 “per service” для всех или отобранных портов
 Для клиентов - элементом service-ref в web.xml или ejb-jar.xml с
опциональным параметром port-name
 Для сервера – элементом port-component в webservices.xml
o Stateless объекты
o Часто используются цепочками, где сообщение передается вдоль цепочки в одну
сторону, а потом ответ – в обратную
o Все экземпляры одного обработчика эквивалентны между собой, может
использоваться пул
o Клиентские обработчики, а также J2SE endpoint обработчики могут быть как одно,
так и многопоточными. EJB endpoint – только однопоточными.
o handleRequest вызывается на сервере / клиенте перед доставкой сообщения
сервису
o handleResponse вызывается на сервере / клиенте перед доставкой ответа
клиенту
o handleFault вызывается
 на клиенте перед получением клиентом SOAP ошибки.
 На сервере перед генерацией SOAP ошибки
o JAXRPCException на сервере вызывает генерацию SOAP fault сообщения, на
клиенте – RemoteException. В последнем случае информация об исходном
исключении утрачивается
o Если возбуждают любой операцией RuntimeException, то вызывается метод
destroy() и экземпляр сбрасывается
o They cannt communicate with business logic of the client

Контекст выполнения
o Выполняются всегда в том же потоке, что и обслуживаемый endpoint / client.
Соответственно имеют доступ к его JNDI контексту и MessageContext
o Между собой в процессе обработки одного запроса могут обмениваться данными
через MessageContext
 Структура
• containsProperty(String)
• [Object get |void set]Property
• Iterator getPropertyNames()
• removeProperty
 По завершению обработки запроса объект контекста удаляется – между
запросами информацию передать нельзя.
 Endpoint тоже могут получить к нему доступ
• EJB через sessionContext.getMessageContext()
• J2SE через ServletEndpointContext.getMessageContext()
o Доступ к сообщению через SOAPMessageContext, наследника MessageContext.
Дополнительно:
 SOAPMessage getMessage()
 String[] getRoles() – с какими ролями данный обработчик зарегистрирован
в десткрипторе
 setMessage(SOAPMessage)

Реализация
o Реализуют интерфейс - javax.xml.rpc.handler.Handler
 boolean handleRequest(MessageContext)
• для клиента - обработка отправляемого сообщения после посыла, но
до передачи сетевому протоколу
• для сервера – обработка полученного сообщения до вызова endpoint
 boolean handleResponse(MessageContext)
• для клиента - обработка результата вызова перед возвращением
• для сервера – обработка результата вызова endpoint перед
передачей сетевому протоколу
 boolean handleFault(MessageContext) – обработка ошибки, все аналогично
 void init(HandlerInfo config) - инициализация
• параметры берутся из map-а, доступного в HandlerInfo
o Map getHandlerConfig()
o Class getHandlerClass()
o setHandlerClass(Class handlerClass)
o setHandlerConfig(Map config)
• В J2EE окружении данные для описателя берутся из дескриптора.
Set-методы игнорируются.
• В J2SE окружении создается за счет set методов
 void destroy() – сброс.
 QName[] getHeaders() – сообщение контейнеру о том, какие заголовки
будут им обрабатываться
o Чтобы упростить жизнь – дефолтный обработчик GenericHandler
o При отправке сообщения множественные обработчики вызываются как
handleRequest в порядке определения, при получении результата как
handleResponse – в обратном.
o Создание заголовка
 Из MessageContext приведенного к SOAPMessageContext получаем
SOAPMessage
 Из SOAPMessage – SOAPPart, затем SOAPEnvelope, затем SOAPHeader,
затем SOAPHeaderElement
 Создание SOAPHeaderElement элемента

String messageID = new java.rmi.dgc.VMID().toString();


Name blockName = SOAPFactory.newInstance().createName(
"name","prefix","namespace");
SOAPHeaderElement headerBlock =
header.addHeaderElement(blockName);
headerBlock.setActor("…");
headerBlock.addTextNode( messageID );

Регистрация
o Серверная регистрация обработчика - декларативно в Webservices.xml «per port»
в webservice-description
<webservice-description ><port-component><handler>
<handler-name>MessageID</handler-name>
<handler-class>com.jwsbook.jaxrpc.MessageIDHandler</handler-class>
<soap-header>mi:message-id</soap-header>
<soap-role>http://www.Monson-Haefel.com/logger</soap-role>
<init-param>
<param-name></param-name>
<param-value></param-value>
</init-param>
</handler><port-component><webservice-description >

• Soap-header и soap-role элементов может быть много. Каждый


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

o Клиентская в J2SE – port фигурирует как QName

Iterator iter = stub.getPorts();


List handlerChain = new ArrayList();
handlerChain.add(new HandlerInfo(class,handlerConfig,null));
HandlerRegistry registry = stub.getHandlerRegistry();
While(iter.next)
Registry.setHandlerChain(iter.next(), handlerChain)

o Клиентская в J2EE - декларативно в Webservices.xml как «per service»

<service-ref > … <handler>


<handler-name>MessageID</handler-name>
<handler-class>com.jwsbook.jaxrpc.MessageIDHandler</handler-
class>
<soap-header>mi:message-id</soap-header>
<soap-role>http://www.Monson-Haefel.com/logger</soap-role>
<port-name>BookQuotePort</port-name>
<init-param>
<param-name></param-name>
<param-value></param-value>
</init-param>
</handler> … < service-ref >

 Port-name – опциональное указание на то, что обработчик обслуживает


только один из портов, реализующих данный сервис. Необходимо, так как
конфигурируется per-service, а не per-portcomponent

Передача сообщения
o handleRequest
 true – передача следующему обработчику, или отсылка / вызов сервиса
 false – указание на то, что цепочка прерывается и дальше обрабатывать не
надо
• вызывается handleResponse того же обработчика
• вызываются handleResponse предыдущих обработчиков в обратном
порядку
• обработчик, вернувший false, ответственен за переформирование
сообщения
 возбуждение SOAPFaultException – SOAP специфичная ошибка
• не должен возбуждаться на клиенте
• вызывается handleFault того же обработчика
• обработчик ответственен за формирование SOAP Fault части в
handleRequest / handleFault
 JAXRPCException или RuntimeException – сигнализирует об ошибке
времени выполнения.
• На сервере приводит к возникновению Fault с кодом soap:Server.
Дальше обратно все обработчики в установленном порядке.
• На клиенте вызовет java.rmi.RemoteException немедленно, никакие
обработчики более не вызовутся
o handleResponse
 true – вызывается предыдущий обработчик или отсылка / возвращение
клиенту
 false – указание не прерывание цепочки
• на клиенте - пропускаются остальные обработчики и сразу
передается вызывающему коду
• на сервере – сразу отсылается
 JAXRPCException или RuntimeException – ошибка времени выполнения
• На сервере приводит к возникновению Fault с кодом soap:Server.
Дальше обратно все обработчики в установленном порядке.
• На клиенте вызовет java.rmi.RemoteException немедленно, никакие
обработчики более не вызовутся
o handleFault
 true – нормальное распространение
 false – прерываение цепочки и сразу отдача клиенту
 JAXRPCException или RuntimeException – ошибка времени выполнения,
все как обычно, исходное сообщение теряется

UDDI 2.0 – структуры данных

Общие замечания
o Предназначен для хранения очень общих описаний и изначально не связан с
WSDL
o Ориентирован на процесс описания SOA
o Типы страниц
 Белые – контактная информация о компании, УИД-а, бизнес описания
 Желтые – бизнес сервисы по системам категоризации
 Зеленые – техническая информация для описания реализаций бизнес
сервисов
o Представляет собой веб сервис, реализующий стандартный интерфейс на основе
стандартного набора описаний хранимых сущностей
o Основные сущности:
 businessEntity – бизнес или организация, предоставляющие сервисы, то
есть публикатор в регистре. Использует tModel для:
• определения технологии идентификации
• определения технологии каталогизации
 businessServices – коллекция описаний обобщенных сервисов.
 bindingTemplate – описание входной точки для сервиса и привязку сервиса
к технологиям. Использует tModel для ссылки на технологии реализации
сервиса.
 tModel – описание технологии или системы каталогизации, используемые
другими сущностями
• Стандарт UDDI требует, чтобы поддерживались стандартные
технологии классификации:
o Виды индустрии – NAICS
o Продукты и сервисы – UNSPSC
o Географическое местоположение - ISO 3166
• Стандарт UDDI требует, чтобы поддерживались стандартные
технологии идентификации:
o D-U-N-S от Dun & Bradstreet (D&B) - хранит 75 мил кредитных
историй компаний
o Thomas Register Supplier Identifier Code system – онлайн
каталог продукции порядка 200 тыс компаний США и Канады
• Используют друг друга для каталогизации
• Используется для хранения ссылки на WSDL документ, служащий
собственно описанием технологии сервиса
 publishAssertion – описание логической связи между двумя businessEntity
o УИД-ы имеют – businessEntity, businessServices, bindingTemplate и tModel
o Вспомогательные коллекции (УИД не имеют):
 identifierBag – коллекция идентификатров какой-то businessEntity в
различных системах идентификации
 categoryBag – коллекция привязок businessEntity, businessServices и
tModel к различным системам каталогизации
o Отношения: publishAssertion *-2 businessEntity -* businessService -*
bindingTemplate *-* tModel

businessEntity – описание бизнес сущности


o схема – discoveryURLs?, name+, description*, contacts?, businessServices?,
identifierBag?, categoryBag?
o Атрибуты
 businessKey – UUID автоматически генерируемый при создании сущности
o discoveryURLs(discoveryURL+) – коллекция адресов, по которому описание
сущности может быть получено на основе GET метода. Каждый адрес
discoveryURL определяется атрибутами:
 Тип адреса задается атрибутом useType, который принимает значения:
• businessEntity – на описание создаваемое регистром
автоматически, когда сущность добавляется или изменяется. Та
• businessEntityExt – на дополнительное описание, предоставляемое
на регистром
o name – просто наименование организации
o description – описание организации
o contacts – опциональная коллекция контактов, каждый описывается элементом
contact, состоящим из суб элементов: description, personName, phone, email,
address
o identifierBag – опциональная коллекция идентификаторов, каждый из которых
принадлежит к свой системе идентификации, описываемой сущностью tModel.
Содержит дочерние элементы keyedReference с атрибутами:
 keyName – наименование значения свойства
 keyValue – значение свойства
 tModelKey – ИД технологии, реализующей идентификатор
o categoryBag – опциональная коллекция привязок бизнес сущности к различным
технологии классификации. Содержит дочерние элементы keyedReference с
атрибутами:
 keyName – наименование свойства в рамках классификатора
 keyValue – значение свойства
 tModelKey – ИД технологии, реализующей классификатор
businessServices, businessService и bindingTemplate – описание сервиса
o Каждый элемент коллекции – businessService(name*, description*,
bindingTemplate+, categoryBag)
o Атрибуты businessService
 serviceKey – UUID автоматически генерируемый
 businessKey – ссылка на бизнес сущность, к которой относится сервис. В
принципе несколько бизнес сущностей могут разделять сервис, но
управляется она в рамках сущности, на которую ссылается данный атрибут
o Входная точка - bindingTemplate(description*, accessPoint|hostingRedirect,
tModelInstanceDetails)
 Атрибуты:
• serviceKey – ссылка на описание сервиса
• bindingKey - ???
 accessPoint –URL входной точки сервиса. Единственный для шаблона.
Если входных точек несколько, то описание шаблона надо размножать.
• В атрибуте URLType указывается тип – mailto, http, https, ftp, phone,
other
• В соответствии с BP данный элемент является обязательным
 tModelInstanceDetails(tModelInstanceInfo+) –коллекция ссылок на
технологии реализации сервиса.
• Веб сервис обязательно должен описываться WSDL документом
o указывается ссылка на tModel, которая смотрит на
определение port из WSDL документа.
o tModel должна иметь тип uddi:types и относиться к категории
wsdlSpec
• Ссылка в виде УИД задается как атрибут tModel элемента
tModelInstanceInfo

tModel – описание технологии


o Ссылка на описание какой-то технологии – таксономия, модель данных,
категоризации, идентификации или любой технической. Аналог пространства
имен
o Используется в identifierBag, categoryBag, address и publisherAssertion
o Для веб-сервиса определяет совместимость с какой-то спецификацией,
использование какой-то технологии или указывает на спецификацию самого
сервиса как WSDL документ
o Должна бать отнесена к одной из 16 стандартных категорий – UDDI types.
Например – tModel (базовый тип), identifier, categorization, specification, wsdlSpec
(модель, ссылающаяся на WSDL документ), relationship, postalAddress,
specification, xmlSpec, soapSpec, protocol, transport, signatureComponent,
unvalidatable, checked, unchecked
o checked, unchecked – проверка корректности значений на основе
keyedReference
o Структура (name, description*, overviewDoc?, identifierBag?, categoryBag?)
o Атрибуты:
 tModelKey – УИД модели, по которому на нее ссылаются. В отличии от
других UUID для модели должен иметь префикс uuid:
 operator
 authorizedName
o Name – не должно быть уникально в регистре
o overviewDoc(description*, overviewURL)
 description – может включать атрибут xml:lang
 overviewURL – указывает на описание технологии, доступное через GET
• Для веб сервиса на биндинг или тип порта внутри WSDL документ в
форме xpointer
• Для таксономии – на HTML документ с описание
• На это есть вопрос
o identifierBag – опциональная коллекция идентификаторов. Используется только
для keyName="uddi-org:isReplacedBy". Описывает замену одной модели на
другую, например из-за версионности. Содержит дочерние элементы
keyedReference с атрибутами:
 keyValue – значение свойства
 tModelKey – ИД технологии, реализующей идентификатор
o categoryBag – опциональная коллекция привязок к различным технологии
каталогизации. Содержит дочерние элементы keyedReference с атрибутами:
 keyName – наименование в рамках классификатора
 keyValue – значение в рамках
 tModelKey – ИД технологии, реализующей классификатор
В частности используется для указания совместимости веб сервиса с BP
стандартом:
<keyedReference
tModelKey="uuid:65719168-72c6-3f29-8c20-62defb0961c0"
keyName="ws-I_conformance:BasicProfile1.0"
keyValue="http://ws-i.org/profiles/basic/1.0" />

publicAssertion – взаимные отношения двух сущностей


o Содержит элемент – fromKey, toKey, keyedReference.
 Все три обязательны
 В keyedReference атрибуты keyName / keyValue могут быть «»
o Чтобы отношение было валидным надо, чтобы оно было определено в обе
стороны
o Может использовать как моникер, когда оба конца указывают на одну
организацию
o Категории отношений, поддерживаемые в UDDI ()
 /AssociationType/RelatedTo
 /AssociationType/HasChild
 /AssociationType/EquivalentTo

Использование WSDL посредством tModel


o tModel создается для каждого WSDL документа, описывающего сервис.
o Описывается serviceType, а не конкретным service. Так как один WSDL документ
должен описывать технологию доступа ко всем родственным сервисам в рамках
репозитория.
o Соответственно WSDL документ может не содержать service / port элементы
o Для веб сервиса overviewURL указывает на биндингили тип порта в WSDL
документе в форме xpoint

http://www.Monson-Haefel.com/jwsed1/BookQuote.wsdl
#xmlns(wsdl=http://schemas.xmlsoap.org/wsdl/)
xpointer(/wsdl:definitions/wsdl:portType[ @name="BookQuoteBinding"]

o tModel должна посредством categoryBag привязываться к keyName=uddi-


org:types со значением keyValue=wsdlSpec
o Реальная точка доступа к сервису указывается как bindingTemplate /accessPoint.
Соответственно для каждой точки доступа внутри WSDL документа создается
отдельный bindingTemplate
UDDI 2.0 – WS API

Общие замечания
o Каждый бизнес должен регистрироваться только на одном операторе и в
дальнейшем все изменения вносить только на нем. Не поддерживаются
технологии распространения данных
o Доступ через SOAP веб сервис на основе Document/Litera
o Два сорта API – inquiry и publishing
o Допускается только UTF-8 кодировка, поэтому не вполне BP совместима
o Не поддерживает использование заголовков
o Пространство имен – urn:uddi-org:api_v2
o Версия API определяется атрибутом generic=”2.0”
o В HTTP пакетах должен быть заголовок «SOAPAction», значение не важно
o Publishing API поддерживается только через HTTPS
o Запросы синхронные только через HTTP(s)
o Для обновления необходимо предоставлять все описание, нельзя обновить
только, например, одно свойство
o Максимальный объем SOAP пакета – 2 мб
o Inquiry операции:
 Authentication/Authorization Operations
 Save Operations
 Delete Operations
 Get Operations
НЕТ операций modify и post
o Выделенные вопросы
 Return zero or more description of given web services – find_binding
 Complete descriptive details about web services – get_serviceDetail

Inquiry Find операции


o Разновидности
 find_business – работа с businessEntity
 find_relatedBusiness – работа с publisherAssertion
 find_service – работа с businessService
 find_binding – работа с bindingTemplate. Получение технического
описания конкретного сервиса
 find_tModel – работа с tModel
o Принципы вызова
 Корневой элемент - <xxxxx generic="2.0" xmlns="urn:uddi-org:api_v2">
 Внутри
• фрагменты описаний сущностей, по которым осуществляется поиск -
identifierBag, categoryBag, name, tModelBag, и findQualifiers,
discoveryURL
• опции поиска – findQualifiers(findQualifier*)
o Варианты - exactNameMatch, caseSensitiveMatch,
sortByName{Asc|Desc}, sortByDate{Asc|Desc}, orLikeKeys,
orAllKeys, combineCategoryBags, serviceSubset, andAllKeys
• Атрибуты:
o Generic – версия API
o maxRows – максимальное число результатов
o truncation – можно обрезать результат, если он слишком
длинный
o operator – кто будет выполнять запрос
Поиск по categoryBag
• Можно искать совместно с identifierBag, результат - find_business и
find_tModel
• Логика AND
 Поиск по identifierBag
• Можно искать совместно с categoryBag, результат - find_business и
find_tModel
• Логика OR
 Поиск по name
• К концу прибавляется % по умолчанию
• Можно самому также использовать %
• Логика OR
 Поиск по tModelBag
• Используется в find_business, find_service, and find_binding
• Логика AND
o Результат вызова
 Структура businessList(businessInfos*), где businessInfos – элемент одной из
искомых сущностей
 Атрибуты – Generic, truncated, operator
 В случае ошибка возвращается элемент dispositionReport

Inquiry Get операции


o Разновидности
 get_businessDetail – работа с businessEntity
 get_businessDetailExt – работа с businessEntityExt
 get_serviceDetail – работа с businessService, получение технического
описания одного или многих сервисов
 get_bindingDetail – работа с bindingTemplate
 get_tModelDetail – работа с tModel
o Внутри элемент xxxKey c UUID-ом
o Возвращается элемент xxxDetail, внутри которого набиты описания

Publishing – общие замечания


o Только через HTTPS
o Основные операции
 Авторизация
• get_authToken – результат затем вкладывается в каждый запрос как
элемент authInfo
• discard_authToken
 save, delete, get
o В результате получаем коллекцию измененных сущностей или dispositionReport
o Набор операция – SAVE / DELETE / GET

Publishing Save
o Разновидности
 save_business – работа с businessEntity
 save_service – работа с businessService
 save_binding – работа с bindingTemplate
 save_tModel – работа с tModel
 add_publisherAssertions – работа с publisherAssertion
 sett_publisherAssertions – работа с publisherAssertion
o Вызов - save_something(authInfo, some-data-structure*). Атрибуты – generic,
operator и т.д.
o Ответ – somethingDetail(some-data-structure*)
o publisherAssertion – добавлять два раза, чтобы связь была взаимной

Publishing Delete
o Разновидности
 delete_business – работа с businessEntity
 delete_service – работа с businessService
 delete_binding – работа с bindingTemplate
 delete_tModel – работа с tModel
 delete_publisherAssertions – работа с publisherAssertion
o Каскадные опции
 delete_business
• удаляются соответственно businessService, bindingTemplate и
publisherAssertion
• bindingTemplate – не удаляются, если на них установлен редирект
• все остальное не удаляется, если на него есть другие связи
• tModel – удалять только специально предназначенной операцией
 delete_service - удалятся дочерние bindingTemplate с теми же
ограничениями
 delete_tModel
• не удаляются, а скрываются из поиска для find операции.
• Остаются доступными для получения через get операции:
getRegisteredInfo и get_tModelDetail
• Чтобы удалить совсем – к администратору
 delete_publisherAssertions – удаляются по значению обоих ключей
fromKey, toKey, так как не имеют УИД
o Возвращается в любом случае dispositionReport либо в Fault, либо в Body.
Если все нормально, то код ошибки 0 и E_success

Publishing Get
o Разновидности
 get_assertionStatusReport – отчет по publisherAssertion
 get_publisherAssertions – список publisherAssertion
 get_registeredInfo – сокращенный список businessEntity и tModel
o get_assertionStatusReport(authInfo, completionStatus) – получение отчета по
статусам
 Значения completionStatus - status:complete, status:toKey_incomplete и
status_fromKeyIncomplete
 Возвращается элемент assertionStatusReport(assertionStatusItem*)
 assertionStatusItem – обычный publisherAssertion, плюс
• атрибут completionStatus
• элемент keysOwned(toKey | fromKey) – какая сторона принадлежит
пользователю, выполнившему запрос
o get_publisherAssertions
 всех, видимых и невидимых
 возвращает коллекцию publisherAssertions, атрибут authorizedName
показывает кому они принадлежат
o get_registeredInfo
 Возвращает registeredInfo(businessInfos(businessInfo*),
tModelInfos(tModelInfos*))
 businessInfo – описание сущности
• атрибут – businessKey
• Элементы
o Name
o serviceInfos(serviceInfo)
o serviceInfos атрибут - name
o serviceInfo атрибуты – businessKey и serviceKey
 tModelInfo – описание модели
• атрибут – tModelKey
• Элементы
o Name

Сообщение об ошибке - dispositionReport


o Стандартное - soap:Fault(soap:faultcode, soap:faultstring, soap:faultactor?,
soap:detail?)
o Внутри detail – dispositionReport(result(errInfo))
o Атрибуты dispositionReport стандартные – generic и operator
o Атрибут result – errno
o Атрибут errInfo – errCode, один из 24 стандартных, в текстовом виде, с
префиксом “E_”
o Внутри errInfo текст про ошибку
o Возвращается сообщение только про одну ошибку. Следующая – при
исправлении и повторной отправке
o Может возвращаться если все нормально, но результата нет. В этом случае идет
не в Fault, а в Body. Код ошибки 0 и E_success
Например, при Delete операциях:

<dispositionReport generic="2.0" operator="operatorURI"


xmlns="urn:uddi-org:api_v2">
<result errno="0" >
<errInfo errCode="E_success" />
</result>
</dispositionReport>

UDDI 2.0 – JAXR 1.0 API

Общие замечания
o Java API for XML Registeries
o Рамочное для доступа к ebXML, UDDI и т.д. регистрам, каждый J2EE поставщик
наполняет своим содержанием
o Два уровня – 0, базовый для доступа к UDDI, и 1 – более продвинутый для
общения с ebXML.
o Описание совместимости как CapailityProfile, если вызываем метод на того
уровня – возбуждается UnsupportedCapailityException
o WS-I BP позволяет использовать только 1 уровень
o Два основных пакета:
 javax.xml.registry
• Query (Inquiry)
o QueryManager – уровень 1
o BusinessQueryManager – уровень 0
o DeclarativeQueryManager – уровень 1, SQL язык запроса
• Life Cycle (Publishing) API
o LifeCicleManager – уровень 1
o Business LifeCicleManager – уровень 0
 javax.xml.registry.infomodel – используемая ими модель данных
o Архитектура
 JAXR API provider – предоаствляемая поставщиком реализация
унифицированного доступа к регистрам. Выдает клиентам интерфейсы
различного уровня доступа. Сам вызывает плагины поставщиков регистров
различного типа – UDDI / ebXML и т.д. То есть служит прокси, преобразуя
общие операции / типы данных в частные для каждого Registry provider
 JAXR Registry provider – интерфейс, который поставщик регистра
определенного типа предоставляет «JAXR API provider»-у
 Клиенты – использует единый интерфейс доступа, предоставляемый
«JAXR provider» для прозрачного доступа к регистрам различного типа за
провайдером - прокси
o Возврат ошибок
 Серверные - возвращаются только как коллекция наследников
RegistryException в BulkResponse
 Клиентская - возбуждается JAXRException
o Безопасность
 Клиент должен аутентифицироваться не всегда, только на запросах,
связанных с изменением данных
 JAXR API provider аутентифицируется в JAXR Registry provider от имени
клиента
 Методов работы с AUTH_TOKEN в API нет, так как он относится только к
одному специфическому типу регистров – UDDI, а данное API обобщенное
o findConcepts НЕ поддерживает поиск по спецификациям

Основные объекты
o Служебные типы
 Key – представляет UUID, единственное String свойство id. Не все объекты
модели его имеют, только
• Organization
• Service
• ServiceBinding
• Concept
• ClassificationScheme
А остальные объекты модели возвращают ложные коды, которые не могут
использоваться:
• Association
• Classification
• ExternalIdentifier
• ExternalLink
• SpecificationLink
• User
 InternationalString – коллекция LocalizedString и общие методы доступа к
значениям по Locale ключу
 LocalizedString – хранение value, уточнено Locale и charsetName
o Фабрика соединений – ConnectionFactory
 newInstance() – создание
 Connection createConnection() – создание соединения
 FederatedConnection createFederatedConnection(Collection) – создание
объединенного соединения для одновременного поиска в нескольких
регистрах на основе коллекции соединений с ними
 Свойство Properties – конфигурационные свойства, из них:
• javax.xml.registry.queryManagerURL – точка входа для Inquiry
• javax.xml.registry.lifeCycleManagerURL – точка входа для Publishing.
Если не задавно, то берется та же, что и в предыдущем случае
• javax.xml.registry.security.authenticationMethod – метод
идентификации, основной UDDI_GET_AUTHTOKEN
• javax.xml.registry.uddi.maxRows – максимальная длинна
получаемого с ответом набора результатов. На это есть вопрос
 J2EE контейнеры обычно поставляют уже сконфигурированную фабрику,
доступ через JNDI, определение, например, в web.xml
<resource-ref>
<res-ref-name>jaxr/UddiRegistry</res-ref-name>
<res-type>javax.xml.registry.ConnectionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>
 В J2SE надо определить системное свойство
javax.xml.registry.ConnectionFactoryClass = <class name>
o Соединение – Connection
 Состояние - close(), isClosed()
 Доступ – Set свойство Credentials. Требуется только для записи в реестр -
lifeCycleManager API
 Получение доступа к сервису – RegistryService getRegistryService()
o UDDI сервис – RegistryService, набор get методов для получения
 основных точек входа:
• BusinessLifeCycleManager
• BusinessQueryManager
 Описание совместимости – CapabilityProfile
 Ссылку на дефолтную технологию описания почтового адреса -
DefaultPostalScheme
 «Сырое» выполнение запроса - String
makeRegistrySpecificRequest( String request)
 BulkResponse getBulkResponse(requestId) – не применим к UDDI
o Фабрика LifeCycleManager – основа для BusinessLifeCycleManager
 Умеет создавать основные сущности, которые расширяют
javax.xml.registry.infomodel.RegistryObject
• Organization => businessEnity
• Service => businessService
• ServiceBinding => bindingTemplate
• Concept => tModel
• Association => publisherAssertion
o Интерфейс редактирования – BusinessLifeCycleManager
 Также используется как фабрика для создания новых объектов. Но пока они
сами или в состав графа не сохранятся методом saveXXX() реального
создания не происходит
o Интерфейс запроса – BusinessQueryManager, наследник QueryManage
 Методы от QueryManage
• RegistryObject getRegistryObject(String id [,String type])
• BulkResponse getRegistryObjects([String objectType]) – объекты
принадлежащие пользователю
• BulkResponse getRegistryObjects(Collection<key>, [String
objectType])
 Собственные findXXX методы, возвращают BulkResponse, где ХХХ это
• Associations
• CallerAssociations
• ClassificationSchemes
• Concepts
• Organizations
• RegistryPackages
• ServiceBindings
• Services
 findXXX методы, возвращающие один объект
• ConceptByPath
• ClassificationSchemeByName
o Результат выполнения редактирования или поиска – BulkResponse
 Содержит коллекцию объектов произвольных типов, что именно зависит от
вызываемого метода. Так, например, для findXXX методов получаем
коллекцию Key объектов. Получаем через getCollection()
 Может содержать коллекцию исключений RegistryException -
соответствующим Fault части, получаем через getExceptions().
• Реально присутствуют наследники - DeleteException,
FindException, SaveException
• Свойства
o Key ErrorObjectKey
o Throwable Cause
o String Message
o String RequestId
o Int Status
o Throwable initCause
 boolean isPartialResponse – признак того, что получены не все результаты
 int getStatus() - JAXRResponse.STATUS_SUCCESS или
JARResponse.STATUS_FAILURE

Объекты модели данных


o Основа для модели данных регистра – RegistryObject
 Основные свойства
• Key key – представление UUID, не все объекты его имеют.
• InternationalString name
• InternationalString description
• Collection Сlassifications – коллекция классификаторов
• Collection ExternalIdentifiers – коллекция дополнительных
идентификаторов
• Collection ExternalLinks – коллекция внешних ссылок
• Collection Associations – коллекция ассоциаций
 Organization getSubmittingOrganization() – публикатор объекта
 LifeCycleManager getLifeCycleManager() – фабрика-менеджер, создавшая
объект
o Ссылка на ресурс, описывающий организацию, вне реестра или в реестре в
зависимости от типа – ExternalLink. Наследник RegistryObject. Фактически
просто обертка вокруг URL
 Два типа ссылок – различаются по имени
• businessEntity – ссылка на XML описание в самом регистре.
Создается регистром каждый раз при обновлении информации. Не
может быть удалена или модифицирована
• businessEntityExt – остальные описания, с которыми пользователь
может работать
 В основном используются для описания организации, но методы работы с
ними определены в RegistryObject
 Основные свойства
• String url
• LinkedObjects – коллекция RegistryObject, которые аннотированы
данной ссылкой
• Name – наследуется от RegistryObject
o Организация – Organization, корень регистра, наследник RegistryObject.
Определяет
 Add / remove / get методы для объектов и их коллекций
• User
• Service
• childOrganisation – имеются в виду непосредственные дети
• DescendantOrganisation – имеются в виду все потомки
• TelephoneNumbers
 Get / set методы для
• primaryContact
• parentOrganisation
• postalAddress
• rootOrganisation (только get метод)
o Контакт – User, представление элемента contacts внутри описания бизнес
сущности, основные свойства:
 Organization
 Collection<EmailAddress>
 personName – не локализуемо
 Collection<PostalAddress>
 Collection<TelephoneAddress>
 Type
o Сервис, предоставляемый организацией – Service. Соответствует UDDI сущности
businessService. Наследник RegistryObject. Сам определяет:
 Свойство ProvidingOrganization
 Коллекцию ServiceBindings с add/remove сервисами для одиночных
привязок и их коллекций.
 Может быть описан коллекцией classification объектов, которые в данном
случае описывают бизнес классификацию сервиса
o Входная точка доступа к сервису – ServiceBinding, Соответствует UDDI сущности
bindingTemplate. содержит
 Коллекция объектов типа SpecificationLink с add/remove c add/remove
методами для объектов и коллекций. Каждая ссылка содержит указание на
Concept в виде свойства SpecificationObject. Concept используются для
описания задействованной технологии, например ссылки на точку входа
внутри WSDL документа:
• Ссылка на WSDL документ, точнее на конкретный binding внутри
него, добавляется как ExternalLink для Concept
• Признак совместимости с BP добавляется как Classification к
описанию Concept
• Указание на то, что данный Concept реализуется как WSDL документ,
добавляется как Classification к описанию Concept
• В соответствии с BP концепт не должен иметь родителя
 AccessURI – входная точка
 Service – ссылка на сервис
 TargetBinding – другая точка доступа для осуществления редиректа

Объекты классификации и ассоциации


o Элемент классификации в определенной схеме – Classification,
 В UDDI представляется как keyedReference, входящий в коллекцию
categoryBag
 основные свойства:
• СlassificationScheme – ссылка на схему
• RegistryObject – классифицируемый объект
• Concept – элемент классификации
• Value- значение в раках классификации
 Создается:
• CreateClassification(schema, name, value) – по name/value ищется
concept в указанной схеме
• CreateClassification(concept)
o Идентификатор в определенной схеме – ExternalIdentifier
 Представляет собой keyedReference, входящий в коллекцию identifierBag
 основные свойства:
• СlassificationScheme – ссылка на схему
• RegistryObject – идентифицируемый объект
• Value - идентификатор
o Схема классификации – СlassificationScheme, представляет собой tModel
реестра
 UUID всегда имеют uddi: префикс
 Ссылки на нее фигурируют в Classification и ExternalIdentifier, которые в
свою очередь являются элементами categoryBag или identifierBag в
регистре
 Может быть внутренней или внешней относительно реестра – isExternal()
• Внутренние схемы реализуются как граф объектов Concept. Могут
быть просмотрены средствами JAXR
• Внешние реализуются как одноуровневая коллекция Concept,
ссылающаяся на документы вне регистра
 Добавление или удаление элементов классификации – [add |
remove]ChildConcept(Concept | Collection<Concept>)
 Получение количества элементов - getChildConceptCount()
 Получение детей как Collection
• Непосредственных - getChildrenConcepts()
• Всех - getDescendantConcepts()
o Представление конкретного элемента tModel (в ситуации, когда содержание
схемы внутреннее), то есть значения в рамках классификации – Concept
 Основные свойства – parent, path, value, СlassificationScheme
 Работа с детьми как Collection
 В UDDI может иметь только одно имя, но LocalizedString
 ExternalLink - наследуется от RegistryObject, указатель на описание
элемента классификации, помещенное вне реестра
 SetValidateURIL() – проверка ссылки при сохранении. Если не выполняется
- JAXRException
 При использовании в SpecificationLink для описания точки входа веб
сервиса, как ссылки на WSDL документ:
• Concept, соответствующий WSDL документу, определяется
глобально, так как может быть много сервисов использующих его для
описания формата вызова
• ExternalLink - соответствует overviewDoc элементу UDDI. BP
требует, чтобы указывал на конкретную привязку в WSDL документе.
• Допускается много ExternalLink , но должна быть определена только
одна
• Указание на то, что используется ссылка на WSDL документ,
добавляется как элемент классификации
o Схема - uddi-org:types
o Значение - wsdlSpec
• Совместимость с BP добавляется как элемент классификации
o Схема классификации - ws-i-org:conformsTo:2002_12
o Значение классификации - http://ws-i.org/profiles/basic/1.0
• Не могут использоваться методы Concept интерфейса, только
RegistryObject. В частности, у такого концепта не может быть
родителя
o Ассоциация двух сущностей по какому-то признаку – Association. В UDDI может
относиться только к организациям и представляет собой publisherAssertion
сущность в регистре.
 Для создания надо две Organization и concept
 Свойства
• AssociationType – ссылка на Concept
• Source / target - связываемые Organization
• Confirmed / ConfirmedBySourceOwner / ConfirmedByTargetOwner –
получение информации о взаимности ассоциаций
• Intramural – признак того, что это фактически декларации и не
требует подтверждения
 Создаются, сохраняются и удаляются независимо от организаций
 Новые типы ассоциаций создаются как Concept
• Схема - uddi-org:types
• Значение – relationship
• Имя – ваше собственное

Использование общее
o Создание фабрики
ConnectionFactory factory = ConnectionFactory.newInstance();
Properties props = new Properties();
props.setProperty("name","value");
factory.setProperties(props);
o Создание соединения и подключение к сервису
Connection connection = factory.createConnection();
RegistryService rs = connection.getRegistryService();
o Получение информации о совместимости
CapabilityProfile capabilityProfile = rs.getCapabilityProfile();
o Получение доступа к основным интерфейсам
BusinessQueryManager bqm = rs.getBusinessQueryManager();
BusinessLifeCycleManager blcm = rs.getBusinessLifeCycleManager();
o Аутентификация (только для записи, для запросов не надо)
PasswordAuthentication passwdAuth =
new PasswordAuthentication(userName, password.toCharArray());
Set creds = new HashSet();
creds.add(passwdAuth);
connection.setCredentials(creds);
o Создание экземпляра UDDI объекта
Organization myOrganization = blcm.createOrganization(companyName);
o Загрузка по UUID
String companyKey = "10c4399a-5f71-0c43-1175-ec1bd516dacc";
Organization myOrganization =
(Organization)bqm.getRegistryObject(companyKey,
LifeCycleManager.ORGANIZATION);
o Сохранение организации
Set organizationSet = new HashSet();
organizationSet.add(myOrganization);
BulkResponse response = blcm.saveOrganizations(organizationSet);

Использование публикации
o Соотнесение организаций
 SaveAssociations
confirmAssociations => add_publisherAssertions
 deleteServiceBindings => delete_binding
 deleteOrganizations => delete_business
 deleteAssociations => delete_publisherAssertions
 deleteClassificationSchemes => delete_tModel
 saveServiceBindings => save_binding
 saveOrganizations => save_business
 saveServices => save_service
 saveClassificationSchemes
saveConcepts => save_tModel
 saveAssociations => set_publisherAssertions
o Получение классификации для организации
Iterator categories = myOrganization.getClassifications().iterator();
while(categories.hasNext()){
Classification classif = (Classification)categories.next();
ClassificationScheme scheme = classif.getClassificationScheme();
}
o Установка идентификатор для организации
ClassificationScheme duns_Scheme =
bqm.findClassificationSchemeByName(null, "dnb-com:D-U-N-S");
ExternalIdentifier dunsNumber =
blcm.createExternalIdentifier(duns_Scheme, companyName, "038924499");
myOrganization.addExternalIdentifier(dunsNumber);
o Создание ассоциаций между двумя организациями
Concept associationType =
queryMngr.findConceptByPath("/AssociationType/RelatedTo");
Association association = lifeCycleMngr.createAssociation(targetOrg,
associationType);
sourceOrg.addAssociation(association);
Set assocSet = new HashSet();
assocSet.add(association);
BulkResponse response = lifeCycleMngr.saveAssociations(assocSet,true);
o Создание сервиса
Service service = blcm.createService(companyName+" Web Site");
InternationalString desc = blcm.createInternationalString( " Web site for
"+companyName);
service.setDescription(desc);
myOrganization.addService(service);
o Создание точки доступа для сервиса
ServiceBinding binding = blcm.createServiceBinding();
service.addServiceBinding(binding);
binding.setValidateURI(false);
binding.setAccessURI("http://www."+companyName+".com/index.html");
o Создание ссылки на binding внутри WSDL документа
Concept wsdlConcept = lifeCycleMngr.createConcept(null,"","");
InternationalString conceptName =
lifeCycleMngr.createInternationalString(domainName+":BookQuote");
wsdlConcept.setName(conceptName);

ExternalLink overviewDoc = lifeCycleMngr.createExternalLink(


"http://xxx.wsdl#xmlns(wsdl=http://schemas.xmlsoap.org/wsdl/) "+
"xpointer(/wsdl:definitions/wsdl:portType[@name=\"BookQuoteBinding\"])"
,
"The WSDL <binding> for this Web service");
overviewDoc.setValidateURI(false);
wsdlConcept.addExternalLink(overviewDoc);

ClassificationScheme uddi_types =
queryMngr.findClassificationSchemeByName(null, "uddi-org:types");
Classification wsdlSpec_Class = lifeCycleMngr.createClassification(
uddi_types,"WSDL Document","wsdlSpec");
wsdlConcept.addClassification(wsdlSpec_Class);

ClassificationScheme wsI_types = queryMngr.findClassificationSchemeByName(


null, ws-i-org:conformsTo:2002_12");
Classification wsIconform_Class = lifeCycleMngr.createClassification(wsI_types,
"Conforms to WS-I Basic Profile 1.0","http://ws-i.org/profiles/basic/1.0");
wsdlConcept.addClassification(wsIconform_Class);

Set conceptSet = new HashSet();


conceptSet.add(wsdlConcept);
BulkResponse response = lifeCycleMngr.saveConcepts(conceptSet);
o Привязка технологий к точке доступа
SpecificationLink specLink = blcm.create SpecificationLink ();
binding.addSpecificationLink(specLink );
SpecLink.setSpecificationObject(wsdlConcept) ;

Использование поиска
o Соотнесение операций
 findOrganizations => find_business
 findAssociations => find_relatedBusiness
 findCallerAssociations => get_publisherAssertions
get_assertionStatusReport
 findServices => find_service
 findServiceBindings => find_binding
 findClassificationSchemes => find_tModel
 findClassificationSchemeByName => find_tModel
 findConcepts => find_tModel
 findConceptByPath => find_tModel
o Типовой вызов
public BulkResponse findOrganizations(Collection findQualifiers,
Collection namePatterns,
Collection classifications,
Collection specifications,
Collection externalIdentifiers,
Collection externalLinks)
throws JAXRException;
o Формирование шаблона по имени
Collection namePatterns = new HashSet();
namePatterns.add("IBM");
o Квалификация процесса поиска
 Типовые квалификаторы
• AND_ALL_KEYS
• OR_ALL_KEYS
• CASE_SENSITIVE_MATCH
• EXACT_NAME_MATCH
• OR_LIKE_KEYS
• SORT_BY_[DATE|NAME]_[ASC|DESC]
Collection findQualifiers = new HashSet();
findQualifiers.add(FindQualifier.OR_ALL_KEYS);
o Получение результата
Iterator results = response.getCollection().iterator();
while(results.hasNext())
Organization org = (Organization)results.next();
doExceptions(response);
o Поиск по классификационному критерию
 Ищутся - Organization, Service, ServiceBinding, ClassificationScheme, and
Concept
 Поиск ведется по содержимому categoryBag раздела
 Если несколько классификаций – по умолчанию AND принцип
ClassificationScheme naics_Scheme =
queryMngr.findClassificationSchemeByName(null, "ntis-gov:naics");
Classification naics_BookWhslrClass =
lifeCycleMngr.createClassification(naics_Scheme,"Book Wholesaler",
"42292");
Collection classifications = new HashSet();
classifications.add(naics_BookWhslrClass);
BulkResponse response = queryMngr.findOrganizations(null, null, classifications,
null,null);
o Поиск по внешнему идентификатору
 Ищутся Organization and Concept
 Поиск ведется по содержимому identifierBag раздела
 Если несколько идентификаторов – по умолчанию OR принцип
ClassificationScheme duns_Scheme =
queryMngr.findClassificationSchemeByName(null, "dnb-com:D-U-N-S");
ExternalIdentifier dunsNumber =
lifeCycleMngr.createExternalIdentifier(duns_Scheme,
"Monson-Haefel, Inc.", "038924499");
Collection identifiers = new HashSet();
identifiers.add(dunsNumber);
BulkResponse response = queryMngr.findOrganizations(null, null, null,
null, identifiers, null);
o Поиск по спецификации
 Ищутся Organization, Service, and ServiceBinding
 Если несколько спецификаций – по умолчанию AND принцип
Concept bookQuote_concept = (Concept)queryMngr.getRegistryObject(
"UUID:2E802060-3CF2-11D7-9590-000629DC0A53",
LifeCycleManager.CONCEPT);
Collection specifications = new HashSet();
specifications.add(bookQuote_concept);
BulkResponse response = queryMngr.findOrganizations(null, null, null,
specifications,
null, null);
o Поиск по внешним ссылкам
 Ищутся businessEntity по discoveryURL элементу описания
 Поле описания заполнять не надо и оно не учитывается
 Если несколько ссылок– по умолчанию AND принцип
String url = "http://sometypeofURL.com/somefile";
ExternalLink link = lifeCycleMngr.createExternalLink(url, "");
Collection externalLinks = new HashSet();
externalLinks.add(link);
BulkResponse response = queryMngr.findOrganizations(null, null, null,null,null,
externalLinks);

WS Sequrity

Общие замечания
o Два уровня – транспортный (SSL / TLS) и XML уровень
o TLS протокол определяется RFC2246
o Web Service Security Assertion – JSR 155
o Web Service Message Security Java API - 183
o К XML уровню также относится single message authentication (security username
tokens)
 Типы токенов – UsernameToken, BinaryToken, XMLToken (не поддерживется
WS-S 1.0)
 Ссылка на токен – SercurityTokenReference. Используется элементы, ИД
ключа или наименования ключей
o Механизм, позволяющий получателю узнать было ли сообщение изменено в
процессе передачи. Специальный токен безопасности с наименованием
«signature»

Транспортный
o Сертификаты м.б. как на клиенте, так и на сервере (основной вариант)
o Если только на сервере – клиент может аутентифицировать сервер, но не
наоборот
o В общем случае может использоваться для аутентификации клиента
o Часть используется совместно с BASIC или HTTPS аутентификацией
o На уровне web.xml транспортная безопасность реализуется как INTEGRAL или
CONFIDENTIAL, без разницы
o «browser specific login mechanism» - BASIC

XML уровень - шифрование


o JSR 106
o Можно шифровать не все, а только те данные, для которых это необходимо –
снижение вычислительной нагрузки и ускорение процесса
o Основной элемент – EncryptedData(encryptedMethod?, keyInfo, CipherData,
EncryptedProperties?)
 Пространство имен - http://www.w3.org/2000/11/temp-xmlenc
 Может быть отдельно в том же XML документе или заменять собой
зашифрованный элемент
 Атрибуты:
• Type – какую часть элемента шифруем:
o http://www.w3.org/2001/04/xmlenc#Element – весь элемент,
включая оба тега
o http://www.w3.org/2001/04/xmlenc#Content – только
содержание
• MimeType – что зашифровали, применяется, например при
шифровании документа целиком, устанавливается в text/xml
 encryptedMethod – описание метода шифрования в атрибуте algorithm,
если отсутствует – забит на клиенте
 CipherData(cipherValue?, cipherReferenceURL?) – зашифрованные
данные
• либо реально содержатся в cipherValue
• либо в элементе на который указывает cipherReferenceURL.
Минимальная порция шифрования – элемент. Используется XPointer
 keyInfo(keyName?, SecurityTokenReference?) – информация об
использованном ключе
 Не могут вкладываться друг в друга, но один может шифровать второй

XML уровень - подпись


o JSR 105
o Проблема – canonicalization, вычисление дайджеста двух XML элементов с
одинаковым содержанием и структурой, но разной разметкой, например, за счет
пробелов
o Особенности стандарта
 Подписываются любые наборы элементов документа, документ в целом, и
не-XML документы
 Подписываемое может быть local/remote объектом, в последнем случае
достижимым через URL
 Подпись может хранится как внутри элемента, так и включать его в себя
 Множественные подписи, различающиеся по семантике применения
 Могут подписываться binary encoded data – картинки и т.д.
 Подпись может использоваться для аутентификации
o Основной элемент – Signature(SignedInfo, SignatureValue, KeyInfo?, Object* )
 Пространство имен - http://schemas.xmlsoap.org/soap/security/2000-12
 Ссылка на то, что подписали – signature/SignedInfo/Reference#URI=”#ИД
подписанного элемента”.
• Подпись может быть как внутри элемента - enveloped, включать
подписанное содержание в себя – enveloping, лежать рядом -
detached. Формат ссылки не меняется
• Enveloping – полезно, когда в подпись надо включить
дополнительные подписываемые данные, а модифицировать
подписанный документ нельзя
• Detached – когда совсем нельзя трогать XML документ, полученный в
виде файла или к нему нет доступа, соответственно подпись в
отдельном файле. В частности применяется в SOAP сообщении –
подпись выносится в заголовок
 SignedInfo(canonicalizationMethod, SignatureMethod, Reference+) –
информация о том, чего подписываем
• SignatureMethod – алгоритм подписи в атрибуте algorithm
• canonicalizationMethod – алгоритм канонизации содержания
документа в атрибуте algorithm. В процессе производится:
o удаление всех несущественных подробностей фрагмента
документа
o стандартизации фрагмента, в целях эквивалентного
представления фрагментов с одними и теми же данными
• Reference(Transforms*, DigestMethod, DigestValue) - ссылка по
атрибуту URL на то, что собственно подписывали, плюс
o Transforms – как трансформировали содержание
o DigestMethod – алгоритм получения дайджеста
o DigestValue – значение дайджеста, которое собственно говоря
и подписывается
Одновременно могут подписываться данные многих источников.
Может за счет URL подписывать и информация о самом ключе
 SignatureValue – получившееся в результате значение подписи. При
проверке
• сначала сравнивается подпись DigestValue и SignatureValue
• затем вычисляется DigestValue для подписанных данных по
Reference#URL
 KeyInfo – информация о ключе, которым можно проверить подпись –
сертификат, сам ключ, алгоритмы. Элемент опциональный, так как
получатель может все знать и сам
 Object – подписанный объект для Enveloping подписи
o Архитектура инфраструктуры подписи
 Централизованная - единый центр
• Легче конструировать и поддерживать
• Все транзакции идут через ненадежный интернет
• Единая точка более подвержена атакам и отказам
• Не подходит для банков, брокерских контор и т.д. – когда реестр
пользователей есть ключевой элемент бизнеса
 Распределенная федеративная структура
• Участники – пользователь, поставщик услуги, поставщик
идентификации
• Может предоставлять SSO, но не обязана

В заголовке SOAP пакета


o Стандартный заголовок wsse:Security, внутри могут быть ключ, подписи, токены
o Ключ в зашифрованном состоянии – xenc:EncryptedKey.
 Аналог EncryptedData, но добавляется элемент
xenc:ReferenceList(xenc:DataReference*) – сслыки на EncryptedData
элементы, где данный ключ применяется.
 Сама ссылка как атрибут URI, зашифрованный элемент EncryptedData
должен иметь атрибут Id
o Токен – место хранения информации, как-то связанной с безопасностью
 UsernameToken(Username, Password)
 BinarySecurityToken
• атрибуты – valueType, EncodingType, id. Содержание – текст
элемента
• часто содержат открытый ключ, например для проверки подписи
 На токен ссылаются через SecurityTokenReference(Reference).
• С атрибутами id у первого и URI у второго
• Может использоваться внутри KeyInfo если один ключ используется
для множества подписей

Специализированные XML языки


o SAML – security assertion markup language
 Цель – обмен информацией при авторизации и иаутентификации
 Содержание – утверждение относительно
• сущностей: персоналий или систем, идентифицированных в
некотором домене безопасности
• атрибутов этих сущностей
• утверждений относительно возможности доступа к ресурсам,
сформированных на основании сущностей и атрибутов
 Определяет
• Синтаксис и семантику сообщений с утверждениями
• Протокол на основе запросов – ответов
• Правила исползования утверждений стандартными транспортами и
API
 Одна из основных целей – использование в составе SSO
o XACML – extensible access control markup language
Описание конфигурации доступа в XML виде + язык запросов и ответов

Ответы – Permit, Deny, Indeterminate, Not Applicable

Артефакты

• PEP – police enforcement point – получает запрос к ресурсу и
собственно разграничивает доступ
• PDP – police decision point – ответчает на XACML запрос от PEP
o XKMS – xml key management specification
 Спецификация на запросы и ответы протокола обмена ключевой
информацией.
 Язык интерфейса к PKI инфраструктуре. Основные типы запросов
• Register
• Locate
• validate
 Делится на
• XKISS - xml key information service specification
• XKRSS - xml key registration service specification

WS-Security
o Реализация на основе SOAP заголовков
o Обеспечивает
 Целостность – за счет XML подписей
 Конфиденциальность – за счет XML шифрования
 Работа с заголовками, телом, приложениями и любыми их комбинациями
o Поддерживает технологии аутентификации – пароль / логин и сертификаты
o Криптографические технологии – Kerberos, PKI, SAML и т.д.
o Заголовок безопасности посредством actor адресован получателю обработчику,
конечному или промежуточному
o В конверте мб несколько security заголовков, адресованных разным получателям
посредством actor.
 Не может быть два заголовка с одним actor
 Информация для разных получателей должна быть в разных загловках
 Заголовок без actor может использовать кем угодно, но не может быть
удален до получения конечным получателем
 Новый заголовок должен добавляться до старого
o Получатель может
 Добавить один или несколько дочерних элементов в существующий
заголовок, адресованный одному получателю
 Добавить новый security заголовок для обработки дальше

Реализация
o HTTP Basic аутентификация
 Transport-guarantee = NONE
 Auth-method = BASIC
 Код на клиенте
Stub stub = createProxy();
stub._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, username);
stub._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, password);
stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY,
endpointAddress);
HelloIF hello = (HelloIF)stub;
System.out.println(hello.sayHello(" Duke (secure)" ));
o Mutual аутентификация
 Сконфигурировать SSL соединения
 Transport-guarantee = CONFIDENTIAL
 Auth-method = CLIENT_CERT
 Код на клиенте – аналогично, но
System.setProperty("javax.net.ssl.keyStore", keyStore);
System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);
System.setProperty("javax.net.ssl.trustStore", trustStore);
System.setProperty("javax.net.ssl.trustStorePassword",
trustStorePassword);

Проект Liberty
o To provide an open standard allow individual consumers and businesses to maintain
personal information securely.
o To provide a universal open standard for single sign-on with decentralized
authentication and open authorization from multiple providers.
o To provide an open standard for network identity spanning all network device.
o To provide standards which will lower e-commerce costs and accelerate organizations'
commercial opportunities, while at the same time increasing customer satisfaction.
o НЕ ПРЕДОСТАВЛЯЕТ: «open standard for single operator performs authentication
and authorization by owning and controlling all the identity information»

Архитектура серверная

Общие замечания
o Вместо повторного использования классов – использование крупных компонентов
- сервисов. Больше гранулярность
o Уменьшает сложность, возникающую за счет использования многих железных и
программных платформ. Возможно за счет WS-I стандарта
o Облегчает разработку слабо сцепленных приложений, особенно полезно в
распределенной среде, хотя общепринятых стандартов для поддержки
распределенных транзакций нет
o WS – хорошее интеграционное решение для мелкого и среднего бизнеса,
которым EDI (electronic data interchange) не по карману
o Изначальная поддержка различных типов клиентов
o UDDI – каталог, а не репозиторий сервисов. В нем нет собственно реализации.
o Типы веб сервисов:
 Информационные – частое чтение редко изменяемой информации
 Конкурентное полное выполнение запросов
 Выполнение больших запросов в очередь
o Части веб сервиса
 Клиент
 Интеграционная часть сервиса, ответственная в том числе за
• Аутентификацию
• Проверку формата сообщения
 Обрабатывающая часть сервиса
o Реализация
 Java=>WSDL – легче, но стандарт взаимодействия будет сильно плыть
вслед за интерфейсом
 WSDL=>Java
• стабильнее внешний интерфейс
• лучше применять, когда внешний интерфейс уже стандартизирован
• сложнее в реализации
• Недостаток для перегруженных методов – представляет аргументы и
возвращаемые структуры как уникальные сообщения
o JSE vs EJB
 Основной вопрос архитектуры реализации. Разные возможности и
соответствнно разные реализации
 Если на основе уже готового приложения – в той технологии, которая ближе
к препроцессированию запросов. Если таковое отсутствует – в той, в
которой выполнение запросов
 Мультипоточность – в JSE обрабатывать самим, в EJB – ответственность
контейнера
 Транзакции – в JSE надо ручками через JTA, в EJB – декларативно
 Безопасность – в JSE на уровне компонента реализации, в EJB – с
точностью до метода
 HTTP сессия – только в JSE
 В числе достоинств JSE – по умолчанию любому клиенту доступна любая
операция. В EJB требуется авторизация и раздача прав
o Если хочется, чтобы интерфейс сервиса оставался стабильным максимально
долго имеет смысл плясать от документа, а нет от RPC. В этом случае точкой
фиксации интерфейса становится схема данного документа
o За интеграцию с EIS ответственен «processing layer»
o Если надо выстроить сервис с multi-thread access, то выбирается EJB
архитектура, как уже обеспечивающая корректную многопоточную обработку
запросов

Реализация
o Параметры и методы
 крупные, вплоть до XML документа со всем контекстом операции.
 ArrayList / Collection не допустимы, только []
 Используются бины без параметров в конструкторе, т.к. не возможно
обеспечить их правильный порядок
 Лучше использовать сложные по структуре JAX-RPC типы ссылающиеся
друг на друга, чем единые большие плоские
 Встроенные типы для поддержки MIME
• image/gif java.awt.Image
• image/jpeg java.awt.Image
• text/plain java.lang.String
• multipart/* javax.mail.internet.MimeMultipart
• text/xml or application/xml javax.xml.transform.Source
 Массивы MIME типов не поддерживаются
 Лучший путь передать нестандарный тип – фрагмент XML документа в виде
DOM. Производится / потребляется через JAXB
 Value типы не должны иметь public члены, являющиеся final или transient
o Перегруженные методы лучше не использовать
o Работа с исключениями
 Должны быть только проверяемыми, наследоваться от Exception
 Относящихся к технологии быть не должно – конвертировать в бизнес
исключения
 Должны быть сериализуемы
 Проблемы с наследованиям – поля и методы родителя не передаются
 Бизнес исключения – восстанавливаемые, fault – системного уровня, не
восстанавливаемые
o Использование обработчиков сообщений
 Конфигурируются для специфического порта сервиса
 Не рекомендуются для обработки бизнес данных или специальных
запросов / ответов
Состояние клиента сохранить в обработчике не получится. Только
состояние порта, относящееся ко всем методам интерфейса сервиса
 Проблемы с производительностью
 Рекомендуются для реализации системых сервисов – аудит, логирование и
т.д.
o Интероперабельность
 Только literal кодирование
 Сложные типы не должны зацикливаться
 Java-MIME типы не поддерживаются
o Обработка запроса
 Проверка на соответствие схеме, безопасность, трансформация
параметров и прочая предобработка – только перед передачей бизнес
слою, как можно ближе к слою интеграции
 Для параметров, коорые будут дальше представлены как Java объекты,
выполняться проверку данных и маппинг перед передачей бизнес слою
 Обработка асинхроанных запросов
• Запрос с большим массивом данных, получение уникального ИД
• По нему либо периодически запрашиваем результат, либо сервис
вызывает back-url указывая ИД в качестве параметра
 Формировать XML ответ надо как можно ближе к endpoint, чтобы
обеспечить кэширование данных и исключить повторные запросы в бизнес
уровень
 Бизнес уровень должен предоставлять абстрактный ответ, который затем
можно по-разному представить для различных типов клиентов
 Если меняется схема – лучше делать отделную входную точку доступа
 Если используются ссылки на внешние схемы, то лучше их предоставлять
самому:
• Безопасность
• Кэширование загрузки
• В SAX подсовывается содержание на основание системной ссылки
через org.xml.sax.EntityResolver
 Использовать внутреннюю схему данных для работы с Java объектами.
Из/в внешних XML документов переливать через XSLT, можно по частям.
Тогда изменение внешнего формата приведет только к коррекции XSLT
таблиц
 В ООП системе держать XML как можно дальше к границе endpoint,
преобразовывать его в объекты как только можно

Работа с XML документами

 Когда используется Java-MIME маппинг представляются как


javax.xml.transform.Source объекты. Передаются как вложения, поэтому
не совместимы с WS-I
 Можно передавать как String – наиболее совместимое решение
• Так как в итоге SOAP сообщение будет большое – проблемы с
производительностью
• Первоначальный формат будет потерян
 Передавать как xsd:anyType = >SOAPElement. Дальше через JAXB
переливать в объекты. Чтобы использовать данный вариант надо идти от
WSDL к Java. Если к документу привязать схему, то интерфейс увидит его
как Object, а весь сервис завяжется на схему, что плохо.
 Документ хорошо разбивать в процессе обработки на несколько
фрагментов, которые распределять по обрабатывающим компонентам
 Документно центрированная обработка используется когда
• Схема документа слишком сложна и не может быть замаплена на
классы
• Часто изменяется
• Из всего документа интересен только фрагмент
 Архитектурный шаблон – XMLDocumentEditor (аналог DAO)
• Оснонывается от абстрактного редактора
• Устанавливается документ как источник данных
• Получаем и сохраняем бизес-объекты в редакторе
• Держим бизнес уровень вне связи с логикой обработки XML формата
 Документы представлять как можно абстрактнее – Result / Source, чтобы
сделать их независимыми от нижележащего API
 Основные этапы обработки:
• Принимаем запрос
• Проверяем соответствие схемы
• Переливаем в доменные объекты
• Вызываем прикладной слой
• Обратно создаем документ из доменных объектов
• Кешируем документ для обработки дальнейших запросов
• Отсылаем ответ
 В данной модели бизнес-операции и работа с XML не разделяются между
собойа

XML технологии
o SAX
 Событийно ориентированная потоковая обработка. Поэтому парсинг в той
же транзакции, что и бизнес логика
 Хорошо подходит для маппинга, когда структуры соответствуют друг другу
 Очень хорошо, когда интересует только часть документа
 Плохо, когда для обработки требуется сложный контекст, поставляемый
всем документов
 Не требователен к памяти
 Для повторного доступа – обрабатывать все заново
o DOM
 Можно использовать, когда структура не описана или описана только DTD
 Когда документ слишком сложен для SAX
 Очень требователен к памяти
 Позволяет редактировать документ и осуществлять произвольный доступ
 Можно обращаться к элементам повторно
o JAXB
 Средние требования по памяти
 Только необходимая информация в виде POJO объектов
 Документ должен обязательно соответствовать схеме
 Можно обращаться к элементам повторно
o Способы оптимизации проимзводительности
 Для цепочки XSLT преобразования – SAXTransformerFactory. Можно
избежать нехватки памяти, если переливать документ из одного
преобразования в другое как SAX поток
 JDOM удобнее из-за использования коллекций, может быть преобразован
из/в потом SAX событий
 Лучше начать преобразовывать документ еще до того, как он полностью
получен. Но использование SAX еще не гарантирует этого
 Xerses позволяет использовать lazy DOM структуру и кэширование
грамматики – XSD схем
 Парсеры, построители документов и трансформеры можно кэшировать. В
EJB это достигается средствами контейнера как stateless бины
 Таблицы преобразования можно кэшировать как
javax.xml.transform.Templates и использовать в параллель
 Части динамически генерируемых XML можно кэшировать. Лучше
использовать SoftReference<>, чтобы избежать проблем с памятью

Шаблоны проектирования
o Общее
 Service-locator – не является типовым серверным шаблоном, а вот
CommandObject является
o Service Locator
 Составные части:
• ServiceLocator (singleton)
• Chache of links
• Initial Context
• Service Factory
• Business Service
 Скрывает сложность получение первоначального контекста, получение EJB
Home объектов и создания бинов
 Абстрагируется от API, предоставляемого технолгиями и вендорами для
работы с контекстом и создания объектов. Преобразует нативные
исключения в прикладные
 Снижает сложность коды, убирает повторяющиеся фрагменты
 Обеспечивает центральную точку контроля над процессом, управление
жизненным циклом создавемых объектов
 Увеличивает производительность за счет кэширования
 Может брать на себя дополнительную ответственность за проксирование
клиентских вызовов и их промежуточную обработку – превращение в
Business Delegate
 Унификация процедур доступа к удаленным объектам в случае
использования различных технологий и API
 Снижение нагрузки на сеть за счет уменьшения количества вызовов по
созданию фабрик и объектов и кэшированию результатов
 Может использоваться
• Business Delegate и Session Fasade для организации доступа к
удаленным и локальным сервисам соответственно
• Transfer Object Assembler – для доступа к бинам из значений
свойств которых собирается Transfer Object
 Проблема “Type Checking”
• При получении удаленной ссылки на EJB ее надо на основе
PortableRemoteObject.narrow приводить к указанному интерфейсу с
его явным указанием. То есть использовать и наименование в
контексте и класс, которые могут не совпадать при вызове друг с
другом
• Решение – набор константных свойств, ставящих в соответствие
наименованиям бинов требуемые интерфейсы. Либо зашиваем в
класс, либо в отдельном конфигурационном файле
o Business Delegate
 Клиентский шаблон – абстракция бизнес слоя с точки зрения клиента
 Минимизация связи между уровнями презентации и бизнес сервисами
 Кэширование промежуточных данных на стороне клиента
 Уменьшение сетевого трафика за счет кэширования, а также уменьшения
количества сетевых вызовов из-за увеличение степени их
гранулированности
 Управление
• Поиском и получением удаленных ссылок за счет Service Locator
отдельного или встроенного
• Преобразование сетевых и общих инфраструктурных исключений в
прикладные
• Восставновление после неудачного выполнения запрошенной
операции
 Как правило 1:1 соответствует Session Fasade на стороне сервера. Может
быть и много в зависимости от масштабов
 Работа с ссылками на удаленные сущности:
• Два конструктора доступа к сущности – через Home интерфейс и
через сериализованную ссылку – Handle
• Коллекция Handle’s ведется делегатом, клиенту выдается строковый
ключ в коллекции как ИД сущности на стороне сервера
• При обращении клиента по ИД Handle десериализуется с диска и
используется для обращения к серверу
 Может использоваться с В2В клиентом, который отсылает XML файл В2В
адаптеру, тот его партсит и выполняет запрос при помощи делегата
 Может выступать как Proxy / Broker или Adapter, использует Service Locator,
o Session Fasade
 Серверный шаблон
 Проблемы
• Жесткое связывание между клиентом и сервером
• Много мелких удаленных вызовов, грузящих сеть
• Для выполнения некоторой операции на клиент вытаскиваются
удаленные объекты в большом количестве:
o Клиент должен понимать их жизненный цикл, подробности
создания, использования и взаимодействия между собой
o Вытаскивается много лишних данных
o Логика переползает на клиента
 Минимизирует число удаленных объектов, вытаскиваемых на клиента
 Уменьшает связывание клиента и сервера в части знания подробностей
реализации серверной части
 Изолирует клиента от сложности взаимоотношений сервеных частей между
собой
 Реализует workflow работы с прикладными объектами в целях получения
результата, затребованного клиентом. Обеспечивает центральную точку
управления
 Использует Service Locator для получения объектов, на основании которых
работает. Основные типы объектов – Entity, Session, DAO, POJO
 Число фасадов соответствует числу основных предметных областей, на
которые разбивается задача
 В числе прочего может образаться к другим сессионным фасадам
 В качестве центральной точки взаимодействия – идеальное место для
управления транзакциями и доступом
 Чаще всего принимает обращения от выделенного Business Delegate
o Web Service Broker
 Используется когда необходимо:
• Предоставить уже существующие сервисы клиентам.
• Зачастую надо выставлять далеко не все их операции
• Мониторить вызовы и обеспечивать из безопасность
• Выставить в соответствии с открытыми стандартами
• Заполнить промежуток между требованиями и существующими
сервисами
 Не принадлежит к бизнес уровню веб приложения
 Развязывает множество клиентов различного типа и множество сервисов
 Составные части
• Endpoint processor – первичная обработка входящих запросов
• WebServiceBroker c доступными реалиацями: POJOBroker,
SessionBeanBroker, JAXBroker
• Business Service
 При его применении существующий Session Fasade должен быть
отрефакторен для поддрежки локальных обращений
 Трафик увеличивается из-за XML/HTTP протокола

Новые возможности (Java 5/6, SCEA)

RESTFull сервисы
o Определение
 Принцип организации stateless клиент-серверной архитектуры, когда веб
сервисы видны в качестве отдельных именованных ресурсов, допускающих
выполнение ограниченного количества стандартных именованных
операции.
o В большинстве случаев, хотя и не обязательно это HTTP доступ по URL и CRUD
операции
 на основе стандартных HTTP операций
• PUT – обновление существующего ресурса
• GET - получение данных или выполнение запроса
• POST – создание нового ресурса, в ответ обычно данные или статус
операции
• DELETE – удаление ресурса
 На основе только GET/POST операций, когда реальная операция
определяется частью запрашиваемого URl. Особенно полезно, когда
браузер или сервер не поддерживает PUT/DELETE
o Особенности использования
 Всегда stateless. Кэширование данных возможно с целью повышения
производительности считывания редко меняющихся данны. Только для
GET запросов
 Поставщик и потребитель сервиса должны быть полностью осведомлены о
семантике операций и стандартах данных. Формального способа описания
интерфейса пока нет, только вне контекстные договоренности. В будущем
для этого планируется Web Application Description (WADL)
 Обычно применяется в ситуациях низкой пропускной способности среды
или недостатке вычислительной мощности, например мобильные
устройства. В этом случае заголовки и дополнительные слои обработки
SOAP оказываются излишними
 При использовании необходимо открыто публиковать используемые схемы
XML, включать из в дистрибутив, тщательно документировать предусловия
и условия вызова, возможные ошибки
 НЕ возможно использование инфраструктурных расширений,
поддерживающих нефункциональные требования
o SOAP явно излишне когда приложение ограничивается выполнение CRUD
операций, но оказывается лучшим выбором когда
 Необходим формальный контракт для описания предоставляемого
интерфейса
 Архитектура требует удовлетворения сложных нефункциональных
требований – транзакционность, безопасность, Addressing, Trust,
Coordination
 Необходима асинхронная обработка данных, обеспечиваемая за счет
WSRM и новой версией JAX-WS по умолчанию
o Клиенты
 Со стороны веб интерфейса на основе Java Script и биболитек поддержки –
AJAX, Direct WebRemoting (DWR). Подключение RESTFull сервиса в готовое
приложение требует незначительного рефакторинга существующей
системы
 Программный доступ на основе javax.xml.ws.Dispatch<T>
• со следующими основными методами:
T invoke(T msg);
Response<T> invokeAsync(T msg);
Future<?> invokeAsync(T msg, AsyncHandler<T> h);
void invokeOneWay(T msg);
• Создается на основе следующих типов – Source, SOAPMessage,
DataSource, Object
o Поддерживается JAX-WS на основе JSR 224 для Java SE5 / EE5
 Точка доступа реализуется на основе обощенного интерфейса
javax.xml.ws.Provider – являющегося динамической альтернативой
стандартному SEI интерфейсу
 Определяет единственный метод T invoke(T request), ответственный за все.
Внутри него идут разборки с HTTP типом запроса и его содержанием.
Наиболее часто с использованием следующих классов:
• avax.xml.transform.Source. – работа с XML
• javax.activation.DataSource – работа с сообщениями различных MIME
типов
• javax.xml.soap.SOAPMessage – работа с SOAP сообщениями
 Точка доступа аннотируется как @ServiceMode(value = MESSAGE |
PAYLOAD) для определения режима работы с сообщениями
• MESSAGE – разрешено получение и возвращение только
сообщений, соответствующих протоколу биндинга, например SOAP
• PAYLOAD – работа с произвольным XML
 Может быть создан и поднят
@WebServiceProvider
@ServiceMode(value=Service.Mode.PAYLOAD)
public class MyProvider implements Provider<Source>
• в составе сервера
• как standalone приложения
Endpoint e = Endpoint.create( HTTPBinding.HTTP_BINDING,
new MyProvider());
e.publish("http://127.0.0.1:8084/hello/world");
 Для обмена данными между XML и объектами чаще всего используется
JAXB
 обработка ошибок
• 404 код в ответ
• Сообщение с XML представлением данных исключения

Направления развития веб сервисов


o Основная сложность с SOAP – оперативная совместимость.
 Изначально по причине опоры на rpc/encoded – кажется простым в
использовании, но проблемы со сложными структурами данных, а также
совместимости между платформами
 Затем document/literal – проблема из-за практики опоры на уже
существующие схемы данных, не учитывающие специфику веб сервисов
 Остутствие возможности подтверждения приема сообщений, особенно для
document/literal с их неполным описанием схем
 Проблема смешения надструктурных и базовых этапов обработки
сообщений. Расширения имеют смысл только когда одинаково
поддерживаются разными средами
o Основной конкурент – Windows Communication Fundation, предоставляющая ряд
де-факто стандартных надстроек над базовыми сервисами
 XOP/MTOM – оптимизация двоичных данных, включенных в SOAP
сообщение в качестве приложения. Раньше DIME, еще раньше SwA
 WS-Addressing – стандартный формат для идентификации сообщений,
адресатов и дествий. Особенно важно, когда транспорт осуществляется не
над HTTP
 WS-Trust и WS-Secure-Conversation – замена старому WS-Security с
поддержкой более удобного семмитричного шифрования
 WS-ReliableMessaging – надежная доставка сообщений и поддержка
последовательностей
 WS-Coordination – контроль над последовательностью операций в
распределенной сети
 WS-AtomicTransaction – транзакции над SOAP с распределенным
протоколом двухфазного подтверждения транзакций.
 WS-Policy – набор расширений к WSDL, которые позволяют сервисам
указать свои требования к использованию всех этих технологий
o Основные стандарты Sun Java веб сервисов
 JAX-RPC 1.0 – на основе rpc/enc.
• К сожалению поддержка rpc/doc декларировалась, но не требовалась
поддержка многих элементов схемы.
• Ограничивала фукнциональность операций, фактически
дублировался RMI над HTTP. Не использовали асинхронные
операции и другие протоколы данных
 JAX-RPC 2.0 / JAX-WS 2.0
• Добавлены аннотации, JAXB как средство связи с данными,
частично RESTFull сервисы
• Напрямую поддерживает XOP/MTOM, но НЕ другие
вышеперечисленные расширения
 Объявлена программа совместимости с мягкими в рамках проекта
GlassFish, который будет основан на JAX-WS 2.0 и поддерживать уже ВСЕ
стандарты расширения
o Альтернативы
 AXIS
• Обычный был совместим с JAX-RPC 1.0
• Версия 2
o JAX-WS 2.0 и Rest
o Гибкая модель данных AXIOM для работы с SOAP
сообщениями. Возможен частичный парсинг данных по месту
работы с ними
o Привязка объектов к данным – XML Beans, JiBX, JaXB 2.0
o Расширения для обеспечения совместимости с мягкими
стандартами. Фигурируют как модули
 WS-Addressing и безопасность – уже в стандарте
 Проект Sandesha - WS-ReliableMessaging
 WS-Trust / WS-SecureConversation – проект WSS4J
 WS-AtomicTransaction и WS-Coordination – проект
Kandula
 Быстрые и маленькие
• JibxSoap – практически сравним по скорости с RMI
• XFire