Советы и приемы работы с инструментарием разработки Web-сервисов IBM Rational Application Developer.: Часть 1. Не забывайте о странице настройки параметров

Введение

Инструментарий разработки Web-сервисов

IBM Rational Application Developer представляет собой полнофункциональное средство быстрой разработки приложений на базе Eclipse. Он позволяет вам (разработчику ПО) проектировать, создавать, развертывать, тестировать и публиковать приложения, основанные на концепции Web-сервисов. Использование этого инструментария существенно упрощает и автоматизирует процесс разработки функционально совместимых Web-сервисов, соответствующих спецификации WS-I, одновременно повышая его эффективность.

Rational Application Developer имеет богатые возможности по разработке Web-сервисов. Возможно, с некоторыми из них вам еще только предстоит познакомиться. Данный цикл статей, основанный на вопросах, задаваемых пользователями-разработчиками, расскажет вам о некоторых приемах и даст полезные советы, которые помогут вам при разработке Web-сервисов с помощью Rational Application Developer версии 6 и 7.

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

Начнем с Rational Application Developer 6. Rational Application Developer 7 имеет ряд расширенных возможностей, о которых я расскажу чуть позже.

По умолчанию в только что созданном проекте Rational Application Developer 6 поддержка Web-сервисов отключена. Чтобы ее включить, выполните команду Window > Preferences > Workbench > Capabilities, включите все опции в ветке Web Service Developer, как показано на рисунке 1, после чего нажмите кнопку OK.

Рисунок 1. Включение поддержки Web-сервисов
Cписок опций поддержки Web-сервисов с описаниями

Настройки IBM WebSphere

После того как вы включите поддержку Web-сервисов, появится страница настройки параметров Web-сервисов. Я не буду рассказывать обо всех возможных настройках. Вместо этого я подробно остановлюсь на тех, что находятся в ветке Web Services > Code Generation > IBM WebSphere runtime (рисунок 2).

Рисунок 2. Настройки IBM WebSphere
Список опций, детально описываемых далее

Disable data binding and use SOAPElement

Эта возможность крайне полезна при работе с типами данных JAX (Java™ API for XML)-RPC для которых отсутствует поддержка. Мы вернемся к обсуждению этой возможности в разделе Новые возможности Rational Application Developer 7 в конце статьи. Оставим самое интересное напоследок.

Do not overwrite loadable Java Classes

Вспомогательные JAR (Java™ Archive) - файлы часто используются для включения в приложение Java™ 2 Platform, Enterprise Edition (J2EE™) существующего кода, реализующего вспомогательные функции, что облегчает его использование в нескольких проектах без изменений. Тем не менее если вы планируете разрабатывать Web-сервисы на основе существующего кода, вам, возможно, придется столкнуться с некоторыми сложностями. Генерация кода Web-сервиса на основе существующего приложения происходит следующим образом.

  1. Сначала вы генерируете WSDL-файл на основе существующего Java-кода (Java2WSDL).
  2. Затем на основе полученного WSDL-файла вы генерируете (WSDL2Java) файлы, составляющие Web-сервис (вспомогательные Java-классы, дескрипторы развертывания и т.д.)

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

Ошибки компиляции, характерные для данного случая, сопровождаются следующими сообщениями:

  • The method xxx in the type yyy is not applicable for the arguments zzz (Метод xxx типа yyy неприменим для аргументов zzz)
  • The method xxx is undefined for the type yyy (Метод xxx не определен для типа yyy)

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

Generate Java from WSDL using the no wrapped style

Данная опция эквивалентна аргументу WSDL2Java -noWrappedOperations. Она включает режим игнорирования обертывания операций. Если эта опция включена, то для сообщений запроса и ответа будут созданы компоненты Java Beans. По умолчанию эта опция выключена и WSDL2Java будет разворачивать обернутые операции.

Пример WSDL приведен в листинге 1.

Листинг 1. Пример WSDL

                

   <complexType name="Address">
    <sequence>
     <element name="province" nillable="true" type="xsd:string"/>
     <element name="city" nillable="true" type="xsd:string"/>
     <element name="street" nillable="true" type="xsd:string"/>
     <element name="postalCode" nillable="true" type="xsd:string"/>
     <element name="phoneNumber" nillable="true" type="xsd:int"/>
   </sequence>
   </complexType>

   <element name="findAddress">
    <complexType>
     <sequence>
      <element name="name" nillable="true" type="xsd:string"/>
     </sequence>
    </complexType>
   </element>

<element name="findAddressResponse">
    <complexType>
     <sequence>
      <element name="findAddressReturn" nillable="true" type="impl:Address"/>
     </sequence>
    </complexType>
   </element>

   <wsdl:message name="findAddressRequest">

      <wsdl:part element="impl:findAddress" name="parameters"/>

   </wsdl:message>


   <wsdl:message name="findAddressResponse">

      <wsdl:part element="impl:findAddressResponse" name="parameters"/>

   </wsdl:message>
   <wsdl:portType name="AddressBook">


      <wsdl:operation name="findAddress">

         <wsdl:input message="impl:findAddressRequest" name="findAddressRequest"/>

         <wsdl:output message="impl:findAddressResponse" name="findAddressResponse"/>

      </wsdl:operation>

   </wsdl:portType>

Если вы включили опцию no wrapped style, будет сгенерирован класс, приведенный в листинге 2.

Листинг 2. Класс сгенерированный при включенной опции "Generate Java from WSDL using the no wrapped style"

                
 public class AddressBookSoapBindingImpl implements webservice.AddressBook {
    public webservice.FindAddressResponse findAddress(webservice.FindAddress parameters) 
      throws java.rmi.RemoteException {
        return null;
    }
}

Обратите внимание на то, что если данная опция включена, будут сгенерированы компоненты Java Beans запроса и ответа для всех элементов complexType, упомянутых в описании операций WSDL - как верхнего уровня, так и вложенных.

Если вы не выбрали опцию Generate Java from WSDL using the no wrapped style, будет сгенерирован класс, приведенный в листинге 3.

Листинг 3. Класс сгенерированный при выключенной опции "Generate Java from WSDL using the no wrapped style"

                 public class AddressBookSoapBindingImpl
 implements webservice.AddressBook{
    public webservice.Address findAddress
    (java.lang.String name) 
      throws java.rmi.RemoteException {
        return null;
    }
}

Обратите внимание на то, что содержимое элемента было извлечено из обертки перед помещением в компонент Java Beans.

Generate Java from WSDL using the no wrapped array style for WebSphere V6

Данная опция эквивалентна аргументу WSDL2Java -noWrappedArrays. Она включает режим игнорирования обертывания массивов. Узнать подробнее об обертывании массивов можно из статьи "Array Gotcha - Null Array vs. Empty Array".

К примеру, если данная опция включена, то из WSDL-кода, приведенного в листинге 4, будет сгенерирован класс, приведенный в листинге 5. В противном случае будет сгенерирован класс, приведенный в листинге 6.

Листинг 4. Пример WSDL-кода

                
 <complexType name="Address">
    <sequence>
     <element name="province" nillable="true" type="xsd:string"/>
     <element name="city" nillable="true" type="xsd:string"/>
     <element name="street" nillable="true" type="xsd:string"/>
     <element name="postalCode" nillable="true" type="xsd:string"/>

     <element name="phoneNumber" nillable="true" type="impl:ArrayOfPhoneNumber"/>
     
    </sequence>
   </complexType>

<complexType name="ArrayOfPhoneNumber">
  <sequence>
    <element maxOccurs="unbounded" minOccurs="0" 
      name="number" nillable="true" type="xsd:int"/>
  </sequence>
</complexType>

Листинг 5. Класс сгенерированный при включенной опции "Generate Java from WSDL using the no wrapped array style for WebSphere V6"

                
 public class Address  {
   private java.lang.Integer[] phoneNumber;
    public java.lang.Integer[] getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(java.lang.Integer[] phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
…….
}

Листинг 6. Класс сгенерированный при выключенной опции "Generate Java from WSDL using the no wrapped array style for WebSphere V6"

                
 public class Address  {
……
    private webservice.ArrayOfPhoneNumber phoneNumber;

….

    public webservice.ArrayOfPhoneNumber getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(webservice.ArrayOfPhoneNumber phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

}
public class ArrayOfPhoneNumber  {
    private java.lang.Integer[] number;

    public ArrayOfPhoneNumber() {
    }

    public java.lang.Integer[] getNumber() {
        return number;
    }

    public void setNumber(java.lang.Integer[] number) {
        this.number = number;
    }

    public java.lang.Integer getNumber(int i) {
        return this.number[i];
    }

    public void setNumber(int i, java.lang.Integer value) {
        this.number[i] = value;
    }
}

Do not backup and overwrite skeleton bean

Иногда возникает необходимость внести изменения в WSDL-код. После этого можно перегенерировать код skeleton-компонента с помощью мастера Web-сервисов. По умолчанию мастер Web-сервисов заменит существующий skeleton-компонент и всю содержащуюся в нем бизнес-логику новым skeleton-компонентом (при том условии, что включен режим замены файлов).

Чтобы при этом избежать потери бизнес-логики, будет создана резервная копия skeleton-компонента. Мастер Web-сервисов создает резервную копию в том же каталоге, что и новый skeleton-компонент, добавляя к имени файла суффикс ".bak". Мастер создает только одну резервную копию.

Если вы включите данную опцию, мастер Web-сервисов не будет выполнять резервное копирование и замену существующего skeleton-компонента, а будет использовать его вместо нового.

Независимо от того, включена данная опция или нет, вам придется выполнить некоторые действия после внесения изменений в WSDL-код и перегенерирования Web-сервиса. Например, вы создали Web-сервис "Math" имеющий единственную операцию "Add". После этого вы добавили операцию "multiply" в WSDL-код и перегенерировали Web-сервис. Если опция была выключена, то вы получите новый skeleton-компонент без бизнес-логики операции "add". Чтобы ее восстановить, вам потребуется найти резервную копию старого skeleton-компонента и перенести бизнес-логику из него в новый компонент. Если опция была включена, то бизнес-логика останется на месте, но метод "multiply" в skeleton-компоненте не появится.

Может ли Rational Application Developer чем-то помочь в такой ситуации? Конечно! Но для этого вам нужно будет воспользоваться функцией "объединение skeleton-компонентов" ("skeleton merge"), появившейся в версии 7. Мы вернемся к обсуждению этой возможности в разделе Новые возможности Rational Application Developer 7.

Generate beans that implement java.io.Serializable for WebSphere v6

Данная опция эквивалентна аргументу WSDL2Java -genImplSer. После включения этой опции каждый сгенерированный bean-компонент будет реализовывать java.io.Serializable.

Согласно спецификации EJB (Enterprise JavaBeans™) 2.1, объекты, передаваемые в качестве параметров удаленных вызовов, должны быть сериализуемыми. Если вы не станете включать эту опцию и попробуете сгенерировать Web-сервис на основе EJB skeleton-компонента или клиента для EJB Web-сервиса, инструментарий выдаст информационные сообщения, предупреждающие о том, что данный объект должен быть сериализуемым.

Set soapAction field to the operation name

Данная опция эквивалентна аргументу WSDL2Java -soapAction. Если данная опция выключена, то значение соответствующего поля в сгенерированном WSDL-коде равно "" (null), как показано на листинге 7.

Листинг 7. В поле soapAction записан null

                  <wsdl:operation name="sayHello">
       <wsdlsoap:operation soapAction=""/>
       <wsdl:input name="sayHelloRequest">
         <wsdlsoap:body use="literal"/>
      </wsdl:input>
       <wsdl:output name="sayHelloResponse">
         <wsdlsoap:body use="literal"/>
      </wsdl:output>

Если опция включена, то в поле soapAction в WSDL-коде будет записано название операции, как показано на листинге 8.

Листинг 8. В поле soapAction записано "sayHello"

                
 <wsdl:operation name="sayHello">
       <wsdlsoap:operation soapAction="sayHello"/>
       <wsdl:input name="sayHelloRequest">
         <wsdlsoap:body use="literal"/>
      </wsdl:input>
       <wsdl:output name="sayHelloResponse">
         <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>

Мы получали сообщения о том, что клиенты, работающие на платформе SAP Portal или SeeBeyond ICAN, не могут взаимодействовать с Web-сервисами (разработанными с помощью инструментария Rational Application Developer и выполняющимися на сервере приложений IBM ®WebSphere®), если полю -soapAction не присвоено никакого значения в WSDL-коде.

Если клиент Web-сервиса требует, чтобы в поле soapAction было записано значение, отличное от названия операции, вы можете вручную задать значение данного поля в WSDL-коде.

Новые возможности Rational Application Developer 7

А сейчас предлагаю обсудить восхитительные новые возможности Rational Application Developer 7. В Rational Application Developer 7, настройки, управляющие генерированием кода, разделены на две группы: Java2WSDL и WSDL2Java.

Мультипротокольная привязка

На вкладке Java2WSDL, показанной на рисунке 3, находятся настройки наиболее важной из новых возможностей - мультипротокольной привязки.

Рисунок 3. Настройки привязки к HTTP, EJB и JMS
В дереве, в левой части окна, выбраны настройки генерирования кода JAX-RPC

Мультипротокольный Java-API для JAX-RPC представляет собой расширение модели программирования JAX-RPC, добавляющее к существующим возможностям поддержку таких типов привязок, как HTTP (SOAP поверх HTTP), EJB (RMI поверх IIOP) и JMS (SOAP поверх JMS).

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

Использование RMI/IIOP вместо протокола, основанного на SOAP, позволяет достигнуть более высокой производительности за счет исключения избыточной упаковки (marshalling) и распаковки сообщений. Кроме того, это обеспечит поддержку клиентских транзакций в Web-сервисах, построенных на EJB.

Из всех типов привязок только SOAP поверх HTTP соответствует WS-I, поэтому в процессе генерирования кода Web-сервисов, использующих привязки типов EJB или JMS, будет выдаваться предупреждение о несоответствии.

На закладке WSDL2Java, показанной на рисунке 4, вы найдете еще одну замечательную возможность инструментария разработки Web-сервисов IBM Rational Application Developer: SDO-фасад.

Рисунок 4. Настройки, управляющие генерированием SDO-фасадов
В дереве, в левой части окна, выбраны настройки генерирования кода JAX-RPC

Disable data binding and use SOAPElement + Generate SDO facades from Java classes

Спецификации JAX-RPC 1.0 и 1.1 определяют стандартные способы преобразования между подмножеством типов XML Schema и Java. Способы преобразования других типов считаются необязательными, независимо от того, указано это явно или нет и преобразовываются в javax.xml.soap.SOAPElement. К таким типам относятся xsd:choice, xsd:any, xsd:sequence со значением maxOccurs больше единицы и модели вложенного контента (например, элементы анонимного типа (anonymous)).

Несмотря на то, что функциональная совместимость Web-сервисов обеспечивается WSDL и сопутствующими стандартами XML, разработчикам Web-сервисов и клиентов для J2EE не следует забывать о проблеме переноса на эту платформу. К сожалению, на платформе J2EE переносимым преобразованием типа xsd:choice является SOAPElement.

В мире Web-сервисов большинство пользователей программируют на Java, а не разрабатывают XML-документы. Этим пользователям нужен составной тип Java, соответствующий типу XML Schema, а не SOAPElement. И когда им приходится работать с низкоуровневым SAAJ (Java API для SOAP с вложениями), у многих из них возникают сложности. Описанная проблема является одной из самых важных в мире Java Web-сервисов.

Но решена ли она для Web-сервисов, реализованных в сервере приложений WebSphere версий 6.0 и выше? Разумеется! Вы можете выбирать между внесением изменений в схему и отключением привязки данных JAX-RPC с последующим использованием альтернативных технологий привязки.

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

Использования нестандартных методов преобразования данных все еще требует написания некоторого объема кода. В то же время в состав Rational Application Developer 7 входит новый инструмент, автоматизирующий генерирование и адаптацию различных SDO для Java Web-сервисов и клиентов.

Если вы включили как опцию Disable data binding and use SOAPElement так и Generate SDO facades from Java classes, мастер Web-сервисов создаст простые в обращении skeleton- и прокси-компоненты, использующие для параметров и возвращаемых значений SDO или базовые типы Java вместо неудобных SOAPElement.

В библиотеке примеров кода Rational Application Developer 7 есть пример "WebSphere Web services claims SDO" ("Web-сервисы WebSphere используют SDO"), демонстрирующий данную технологию.

Merge generated skeleton file

Эту опцию можно найти, выполнив команду Window > Preferences > Web Services > Resource Management.

Рисунок 5. Опция "Merge generated skeleton file"
Опция "Merge generated skeleton file"

Если данная опция включена и в проекте уже есть файл skeleton-компонента с тем же именем, что и у генерируемого, они будут объединены с сохранением существующей бизнес-логики. К примеру, вы создали Web-сервис Math, имеющий единственную операцию Add. После этого вы добавили операцию multiply в WSDL-код и перегенерировали Web-сервис. Если опция включена, вы обнаружите в коде сгенерированного skeleton-компонента как новый метод multiply, так и уже находившийся там метод Add, содержащий бизнес-логику.

Теперь вы больше знаете о влиянии опций страницы настройки параметров на процесс генерирования кода.

В последующих статьях цикла мы обсудим приемы работы с мастером Web-сервисов, средствами тестирования и мониторинга и общие вопросы генерирования кода Web-сервисов.


Страница сайта http://www.interface.ru
Оригинал находится по адресу http://www.interface.ru/home.asp?artId=17078