Главная > J2EE > Советы и приемы программирования Web-служб: Импорт в WSDL-файлах

Тема Зацепин
268

Java-разработчик 🧩
657
3 минуты

Советы и приемы программирования Web-служб: Импорт в WSDL-файлах

В данной статье объясняются нюансы двух типов операторов import, используемых в Web Services Description Language (WSDL, язык описания Web-служб)

Добавлено : 27 Mar 2009, 19:15

Russell Butek (butek@us.ibm.com)
Инженер-программист, IBM

Содержание

1 Import против include
2 XSD-импорт
3 WSDL-импорт
4 Резюме
5 Ресурсы
6 Об авторах

Операторы import являются простыми, не так ли? Они есть почти в каждом языке программирования или языке описания интерфейсов; если вы читаете эту статью, то, возможно, знаете все, что необходимо знать об import. Итак, почему вы должны прочитать совет по оператору import в файлах Web Services Description Language (WSDL)? Во-первых, существуют два типа операторов import: XSD import и WDSL import. Во-вторых, их соответствующее поведение не совсем идентично. И, в-третьих, хорошо бы знать взаимосвязь между ними.

Import против include

Перед погружением в описание операторов import, разрешите мне сказать о различии import и include. Оператор import работает в другом пространстве имен. Оператор include включает другие описания в текущее пространство имен.

XSD-импорт

Рассмотрим основной XSD import, например, показанный красным цветом в листинге 1. Все что этот оператор делает - это импорт пространства имен из одной схемы в другую. Схема, определяющая пространство имен urn:listing2, импортирует схему urn:listing3. Это все. Никакой файл не импортируется. Обе схемы находятся в одном том же самом файле в листинге 1.

Листинг 1. Адресная книга WSDL, использующая два пространства имен

xmlversion="1.0"?>targetNamespace="urn:listing2"xmlns:tns="urn:listing2"xmlns:listing3="urn:listing3"xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"xmlns:xsd="http://www.w3.org/2001/XMLSchema"/>targetNamespace="urn:listing3"xmlns:xsd="http://www.w3.org/2001/XMLSchema">namespace="http://www.w3.org/2001/XMLSchema"/>name="Phone">name="areaCode"type="xsd:int"/>name="exchange"type="xsd:int"/>name="number"type="xsd:int"/>targetNamespace="urn:listing2"xmlns:listing3="urn:listing3"xmlns:xsd="http://www.w3.org/2001/XMLSchema">namespace="urn:listing3"/>namespace="http://www.w3.org/2001/XMLSchema"/>name="Address">name="streetNum"type="xsd:int"/>name="streetName"type="xsd:string"/>name="city"type="xsd:string"/>name="state"type="xsd:string"/>name="phone"type="listing3:Phone"/>name="GetAddressRequest">name="name"type="xsd:string"/>name="GetAddressResponse">name="address"type="tns:Address"/>name="GetPhoneRequest">name="name"type="xsd:string"/>name="GetPhoneResponse">name="phone"type="listing3:Phone"/>name="AddressBook">name="getAddress">message="tns:GetAddressRequest"/>message="tns:GetAddressResponse"/>name="getPhone">message="tns:GetPhoneRequest"/>message="tns:GetPhoneResponse"/>

Надеюсь, из листинга 1 ясно, что главной целью оператора import является импорт пространства имен. Более распространенным использованием оператора XSD import является импорт пространства имен, которое появляется в другом файле. Вы можете собрать информацию по пространству имен из файла, но не забудьте, что импортируете пространство имен, а не файл (не путайте оператор import с include).

При импортировании пространства имен из файла вы можете обнаружить атрибут schemaLocation в операторе XSD import, но это необязательный атрибут. Как показано в листинге 1, schemaLocation не обязателен, поскольку пространство имен оператора import находится там же (в том же файле), где и сам оператор import. Фактически, если вы укажете место расположение файла (как в листинге 2), XML-парсер может проигнорировать это по своему усмотрению. Атрибут schemaLocation - это попросту подсказка. Если парсер уже знает о типах схемы в этом пространстве имен или имеет какие-либо другие средства их обнаружения, он не обязан переходить в указанное вами место. Такое поведение должно быть для вас еще одним напоминанием о том, что основным назначением оператора XSD import является импортирование пространства имен, а не указание местонахождения объявлений в нем. Естественно, что чаще всего вы будете импортировать пространство имен, о котором XML-парсер ничего не знает, поэтому атрибут schemaLocation становится необходимым и легко забыть, что он является только подсказкой.

Теперь рассмотрим операторы import, выделенные в листинге 1 синим цветом. Поскольку я использую XSD-пространство имен, я должен явно импортировать его. Но это пространство имен является общим. Практически каждый XML-парсер знает о нем. Большинство парсеров часто не требуют указания для него оператора import. Множество инструментальных средств даже не требуют от вас включения оператора import, выделенного красным цветом (в конце концов, импортируемое пространство имен находится в этом же файле), но у вас должно войти в привычку включение оператора import для всех используемых вами пространств имен. Вы не можете знать, что вы или кто-нибудь другой, использующий ваш WSDL-файл, не будет работать с более взыскательными программами.

Еще раз убедитесь, что используемое вами в операторе import пространство имен является таким же, что и targetNamespace импортируемой схемы. Совершенно очевидно, что в показанном в листинге 1 примере вы должны сделать это. Но если вы переместите схему urn:listing3 в файл с именем listing3.xml и импортируете этот файл (как в листинге 2), то это может стать не очевидным. Фактически, это может выглядеть так, как будто вы изменяете пространство имен схемы в файле, используя отличный от указанного в targetNamespace атрибут оператора import. Это является ошибкой. Вы не можете изменять пространства имен. Атрибут пространства имен оператора import должен соответствовать targetNamespace схемы.

Листинги 2 и 3 получены из листинга 1. Листинг 2 - это листинг 1 с перемещенной схемой Phone в другой файл - листинг 3. Оператор import листинга 2 теперь включает атрибут schemaLocation (выделенный синим цветом). Это рекомендуемый способ импорта схемы из файла.

Листинг 2. Адресная книга WSDL, импортирующая XSD-файл для схемы Phone

xmlversion="1.0"?>targetNamespace="urn:listing2"xmlns:tns="urn:listing2"xmlns:listing3="urn:listing3"xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">targetNamespace="urn:listing2"xmlns:listing3="urn:listing3"xmlns:xsd="http://www.w3.org/2001/XMLSchema">namespace="urn:listing3"schemaLocation="listing3.xsd"/>namespace="http://www.w3.org/2001/XMLSchema"/>name="Address">name="streetNum"type="xsd:int"/>name="streetName"type="xsd:string"/>name="city"type="xsd:string"/>name="state"type="xsd:string"/>name="phone"type="listing3:Phone"/>name="GetAddressRequest">name="name"type="xsd:string"/>name="GetAddressResponse">name="address"type="tns:Address"/>name="GetPhoneRequest">name="name"type="xsd:string"/>name="GetPhoneResponse">name="phone"type="listing3:Phone"/>name="AddressBook">name="getAddress">message="tns:GetAddressRequest"/>message="tns:GetAddressResponse"/>name="getPhone">message="tns:GetPhoneRequest"/>message="tns:GetPhoneResponse"/>

Листинг 3. XSD-файл для схемы Phone

xmlversion="1.0"?>targetNamespace="urn:listing3"xmlns:xsd="http://www.w3.org/2001/XMLSchema">namespace="http://www.w3.org/2001/XMLSchema"/>name="Phone">name="areaCode"type="xsd:int"/>name="exchange"type="xsd:int"/>name="number"type="xsd:int"/>

WSDL-импорт

Взгляните на листинги 4 и 5. Они почти такие же, как и листинги 2 и 3. Листинг 4 импортирует листинг 5 как листинг 2 импортирует листинг 3. Но сейчас я использую WSDL-импорт вместо XSD-импорта. Отличия между листингом 2 и листингом 4 выделены синим цветом в листинге 4. Аналогично, отличия между листингом 3 и листингом 5 выделены синим цветом в листинге 5.

Листинг 4. Адресная книга WSDL, импортирующая WSDL-файл для схемы Phone

xmlversion="1.0"?>targetNamespace="urn:listing4"xmlns:tns="urn:listing4"xmlns:listing5="urn:listing5"xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">namespace="urn:listing5"location="listing5.wsdl"/>targetNamespace="urn:listing4"xmlns:listing5="urn:listing5"xmlns:xsd="http://www.w3.org/2001/XMLSchema">namespace="http://www.w3.org/2001/XMLSchema"/>name="Address">name="streetNum"type="xsd:int"/>name="streetName"type="xsd:string"/>name="city"type="xsd:string"/>name="state"type="xsd:string"/>name="phone"type="listing5:Phone"/>name="GetAddressRequest">name="name"type="xsd:string"/>name="GetAddressResponse">name="address"type="tns:Address"/>name="GetPhoneRequest">name="name"type="xsd:string"/>name="GetPhoneResponse">name="phone"type="listing5:Phone"/>name="AddressBook">name="getAddress">message="tns:GetAddressRequest"/>message="tns:GetAddressResponse"/>name="getPhone">message="tns:GetPhoneRequest"/>message="tns:GetPhoneResponse"/>

Листинг 5. WSDL-файл для схемы Phone

xmlversion="1.0"?>targetNamespace="urn:listing5"xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"xmlns:xsd="http://www.w3.org/2001/XMLSchema">targetNamespace="urn:listing5"xmlns:xsd="http://www.w3.org/2001/XMLSchema">namespace="http://www.w3.org/2001/XMLSchema"/>name="Phone">name="areaCode"type="xsd:int"/>name="exchange"type="xsd:int"/>name="number"type="xsd:int"/>

Нужно ли это делать? Если вы запустите любимую программу преобразования WSDL в Java с listing4.wsdl, то получите сообщение об ошибке. В листинге 4 я выделил две ссылки на тип Phone: одну зеленым цветом, другую красным. Зеленая ссылка находится в операторе WSDL message. Этот оператор находит Phone, поскольку является WSDL-оператором, а WSDL-файл импортирует Phone через WSDL-оператор import. Красная ссылка находится в схеме. Эта ссылка не находит схему Phone, поскольку она не импортируется через XSD-оператор import. Вы не можете выйти из схемы для поиска других схем. Вы должны импортировать схемы внутри схем.

Если тип Address не содержит элемент phone и, таким образом, не ссылается на пространство имен urn:listing5, то эта пара (листинг 4 и листинг 5) будет допустимой. Но это не является хорошей практикой импорта информации о схеме WSDL-оператором import. Листинги 2 и 3 предпочтительней листингов 4 и 5. Используйте XSD-импорт для импорта схем. Используйте WSDL-импорт для импорта WSDL.

В качестве примера правильного WSDL-импорта обратите внимание на листинг 4, который не содержит ни операторы binding, ни операторы service. Возможно какой-нибудь другой файл, содержащий binding и service, будет импортировать listing4.wsdl через WSDL-оператор import.

Пара последних комментариев по WSDL-импорту. Аналогично XSD-импорту, атрибут namespace WSDL-оператора import должен быть таким же, как targetNamespace импортируемого WSDL. Атрибут location WSDL-оператора import, аналогично атрибуту schemaLocation XSD-оператора import, является просто подсказкой. Однако, в отличие от schemaLocation, присутствие атрибута location WSDL-оператора import необходимо. (Это не ясно из спецификации WSDL 1.1, но Basic Profile на Web-сайте WS-I указывает на это. (См. раздел Ресурсы.)

Резюме

В данной статье сделана попытка рассказать о следующем:

  • Хорошей практикой является использование XSD-импорта для импорта схем и WSDL-импорта для импорта WSDL.
  • Хорошей практикой является импортирование всех используемых вами пространств имен.
  • Значение атрибута импортируемого пространства имен должно соответствовать импортируемому значению targetNamespace.
  • Основным назначением оператора import является импорт пространств имен. Атрибуты schemaLocation и location фактически являются только подсказками, хотя иногда необходимы.

Ресурсы

Об авторах

Russell Butek является консультантом IBM по Web-службам. Он является одним из разработчиков системы IBM WebSphere Web services, а также членом экспертной группы JAX-RPC Java Specification Request (JSR). Russell Butek участвует в реализации системы AXIS SOAP в Apache, приводя AXIS 1.0 в соответствие с JAX-RPC 1.0. Ранее он был разработчиком IBM CORBA ORB и представителем IBM во многих специальных комиссиях OMG, включая председательство в комиссии portable interceptor. Связаться с Russell можно на butek us.ibm.com.

Теги: j2eeSOAPweb servicesWSDLxml

Еще от автора

Применение WeakHashmap для списков слушателей

В статье от 11мая 1999 года Reference Objects были описаны основные идеи применения ссылочных объектов, но не приводилось детального описания. Данная статья позволит вам получить больше сведений, касающихся данной темы. В основном ссылочные объекты применяются для косвенных ссылок на память необходимую объектам. Ссылочные объекты хранятся в очереди (класс ReferenceQueue), в которой отслеживается доступность ссылочных объектов. Исходя из типа ссылочного объекта, сборщик мусора может освобождать память даже тогда, когда обычные ссылки не могут быть освобождены.

Заставки в Mustang

Согласно определению, данному в Wikipedia, заставка - это компьютерный термин, обозначающий рисунок, появляющийся во время загрузки программы или операционной системы. Заставка для пользователя является визуальным отображением инициализации программы. До выхода версии Java SE 6 (кодовое название Mustang) единственной возможностью применения заставки было создание окна, во время запуска метода main, и размещение в нем картинки. Хотя данный способ и работал, но он требовал полной инициализации исполняемой Java среды до появления окна заставки. При инициализации загружались библиотеки AWT и Swing, таким образом, появление заставки задерживалось. В Mustang появился новый аргумент командной строки, значительно облегчающий использование заставок. Этот способ позволяет выводить заставку значительно быстрее до запуска исполняемой Java среды. Окончательное добавление данной функциональности находится на рассмотрении в JCP.

Совмещение изображений

1 Введение 2 Правила визуализации и пример 3 Совмещение изображений в оперативной памяти 4 Постепенное исчезновение изображения 5 Ссылки и дополнительная информация

Еще по теме

Применение WeakHashmap для списков слушателей

В статье от 11мая 1999 года Reference Objects были описаны основные идеи применения ссылочных объектов, но не приводилось детального описания. Данная статья позволит вам получить больше сведений, касающихся данной темы. В основном ссылочные объекты применяются для косвенных ссылок на память необходимую объектам. Ссылочные объекты хранятся в очереди (класс ReferenceQueue), в которой отслеживается доступность ссылочных объектов. Исходя из типа ссылочного объекта, сборщик мусора может освобождать память даже тогда, когда обычные ссылки не могут быть освобождены.

Заставки в Mustang

Согласно определению, данному в Wikipedia, заставка - это компьютерный термин, обозначающий рисунок, появляющийся во время загрузки программы или операционной системы. Заставка для пользователя является визуальным отображением инициализации программы. До выхода версии Java SE 6 (кодовое название Mustang) единственной возможностью применения заставки было создание окна, во время запуска метода main, и размещение в нем картинки. Хотя данный способ и работал, но он требовал полной инициализации исполняемой Java среды до появления окна заставки. При инициализации загружались библиотеки AWT и Swing, таким образом, появление заставки задерживалось. В Mustang появился новый аргумент командной строки, значительно облегчающий использование заставок. Этот способ позволяет выводить заставку значительно быстрее до запуска исполняемой Java среды. Окончательное добавление данной функциональности находится на рассмотрении в JCP.

Использование потоков

1 Введение 2 Работа с выражениями типа Boolean 3 Класс JoptionPane 4 Приложение-счетчик 5 Ссылки

Перехват необрабатываемых исключений

В статье от 16 марта 2004 года Best Practices in Exception Handling были описаны приемы обработки исключений. В данной статье вы изучите новый способ обработки исключений при помощи класса UncaughtExceptionHandler добавленного в J2SE 5.0.

Использование класса LinkedHashMap

1 Введение 2 Сортировка хэш-таблицы 3 Копирование таблицы 4 Сохранение порядка доступа к элементам 5 Ссылки

Сказ про кодировки и java

С кодировками в java плохо. Т.е., наоборот, все идеально хорошо: внутреннее представление строк – Utf16-BE (и поддержка Unicode была с самых первых дней). Все возможные функции умеют преобразовывать строку из маленького регистра в большой, проверять является ли данный символ буквой или цифрой, выполнять поиск в строке (в том числе с регулярными выражениями) и прочее и прочее. Для этих операций не нужно использовать какие-то посторонние библиотеки вроде привычных для php mbstring или iconv. Как говорится, поддержка многоязычных тестов “есть в коробке”. Так откуда берутся проблемы? Проблемы возникают, как только строки текста пытаются “выбраться” из jvm (операции вывода текста различным потребителям) или наоборот пытаются в эту самую jvm “залезть” (операция чтения данных от некоторого поставщика).