(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Книга по Lotus. Разработка приложений в среде Domino 7: Глава 3 (электронная книга)

Команда Авторов International Technical Support Organization, специалисты International Technical Support Organization, IBM

Глава 1 :: Глава 2

С появлением новой возможности Web-сервисов, в программе Lotus Domino Designer 7 продолжается традиция поддержки новых стандартов для расширения возможностей ее модели быстрой разработки приложений. Web-сервисы позволяют превратить приложения Lotus Domino в Web-сервисы, базирующиеся на сервере Lotus Domino, таким образом увеличивая доступ к данным и обеспечивая обращение к приложениям через множество различных платформ. Благодаря тому, что все они построены на основе открытых стандартов, Web-сервисы - автономные, модульные приложения, способные работать друг с другом, без необходимости полагаться на соединения, запрограммированные пользователем. Так как Web-сервисы позволяют различным приложениям и информационным системам взаимодействовать друг с другом, серверные компоненты могут быть скомбинированы и рекомбинированы на лету, что позволяет компаниям быстро реагировать на постоянно меняющиеся потребности бизнеса и клиентов.

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

  • cервис-ориентированная архитектура: как Web-сервисы согласовываются с SOA (Server-Oriented Architecture);
  • Web-сервисы и язык описания Web-сервисов (Web Services Description Language, WDSL);
  • коммерческие предпосылки использования Web-сервисов;
  • элемент Web-сервиса: добавление простых и комплексных элементов Web-сервиса к приложению ITSO Electronics;
  • экспорт и импорт WSDL-документа;
  • работы с ошибками и исключениями в Web-сервисах;
  • безопасность Web-сервисов;
  • использование Web-сервисов на языках программирования Java и LS2J/LotusScript.

3.1 Сервис-ориентированная архитектура и Web-сервисы

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

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

Необходимость в системах со слабой связью растет из-за того, что с каждым днем возрастает потребность в более гибких бизнес-приложениях, которая, в свою очередь, основывается на том, что бизнес должен адаптироваться к изменчивости внешней среды, например к постоянно меняющимся принципам стратегии, устойчивости коммерческого положения, бизнес-целям, партнерству, состоянию промышленности, а также другим факторам, связанным с бизнесом, которые оказывают влияние на природу бизнеса. При желании вы можете обратиться к бизнесу, быстро реагирующему на изменения окружающей среды, т. е. к бизнесу по требованию (On Demand Business), который меняется в зависимости от того, как реализуются цели. Это необходимо для метода «по первому требованию».

Сервис-ориентированная архитектура не только не является новшеством, но вообще представляет собой альтернативную модель более традиционным, тесно связанным объектно-ориентированным моделям, появившимся в последние десятилетия. В то время как системы, базирующиеся на SOA, не исключают того факта, что отдельные сервисы сами могут быть построены по объектно-ориентированной схеме, схема всей системы сервис-ориентированна. Поскольку данное правило распространяется на объекты, находящиеся в пределах системы, SOA основана на объектах, но в целом не объектно-ориентированная. Различие заключается в самих интерфейсах. Классическим примером одной из самых первых SOA-систем является Common Object Request Broker Architecture (CORBA), оперирующая принципами, схожими с SOA.

В настоящее время SOA использует преимущества языка XML (Extensible Markup Language). В результате описания интерфейсов на языках, основанных на XML, называемых языками описания Web-сервисов (Web Services Definition Language, WSDL)), Web-сервисы обрели более гибкие и динамичные системные интерфейсы по сравнению с разработанным ранее языком описания интерфейса (Interface Definition Language, IDL), использованным в CORBA.

Помимо Web-сервисов существуют и другие способы реализации SOA, такие как CORBA и межплатформенные системы, ориентированные на информационный обмен, например IBM WebSphereТ MQ. Однако для того чтобы превратить ее в архитектурную модель, вам понадобится не просто описание сервиса. Необходимо описать то, как все приложение будет осуществлять последовательность операций между сервисами. Кроме того, необходимо найти подходящее для вашего бизнеса программное обеспечение. Следовательно, SOA должна быть связана с коммерческими бизнес-процессами подобно тому, как ITSO Electronics ориентируется на технические процессы и отображает взаимосвязь между технической и коммерческой стороной дела. Например, плата поставщику за услуги - бизнес процесс, в то время как обновление базы данных ваших электронных компонентов с целью внесения новых компонентов - процесс технический. Таким образом, технологический процесс играет значительную роль в схеме SOA.

3.2 Основы Web-сервиса и WSDL

Web-сервис представляет собой программную систему, предназначенную для поддержки взаимодействия компьютеров через сеть. Интерфейс Web-сервиса описан в формате, который компьютер способен обработать (в особенности WSDL). Другие системы взаимодействуют с Web-сервисом способами, предусмотренными его описанием, с использованием сообщений SOAP, которые обычно передаются посредством HTTP с XML-преобразованием вместе с другими стандартами, связанными с Web. Lotus Domino Designer 7 включает элемент разработки приложений - Web-сервисы, а также встроенную поддержку языка описания Web-сервисов (WSDL). WSDL - это стандарт спецификации для описания сервисов, работающих по сети и основанных на XML. Он обеспечивает поставщиков услуг простым способом описания основного формата запросов к системам вне зависимости от основного времени выполнения.

Ограничения в реализации Web-сервисов в Lotus Domino 7 выражаются в следующем:

  • На «родном» уровне поддерживаются только те элементы, которые предоставляются провайдером.
  • Связь должна выполняться по простому протоколу доступа к объектам (SOAP) с помощью протоколов HTTP POST. Элемент Web-сервиса характеризуется следующими параметрами:
  • Скомпилированный Web-сервис, подобно Web-агенту, представляет собой отдельную автономную программу в базе данных Lotus Domino. Для того чтобы им воспользоваться, необходимо включить Web-сервис или отреплицировать его на сервер, к которому имеется Web-доступ. К нему можно получить доступ с помощью одной из приведенных ниже URL-команд Lotus Domino:
    • ?OpenWebService: используя протокол HTTP POST, запускает Web-сервис. Если использован протокол HTTP GET, то команда ?OpenWebService вернет некоторую информацию об этом сервисе.
    • ?WSDL: запрашивает у Web-сервиса его WSDL-документ.
  • Web-сервис можно протестировать во время HTTP-сессии в режиме предварительного просмотра Lotus Notes или Lotus Domino Designer.
  • Web-сервис имеет те же возможности безопасности, что и агент.
  • Вы можете импортировать существующий WSDL-документ, чтобы сгенерировать каркас Web-сервиса. Каркасный код соответствует описанию Web-сервиса. Затем вы добавляете исполнительный код.
  • В качестве альтернативы можно приступить к созданию Web-сервиса с черновика, написав собственный код на языке Java или LotusScript, чтобы создать описание Web-сервиса.

3.2.1 Документ WSDL

Документ WSDL определяет Web-сервис и включает в себя приведенные ниже элементы:

  • Сервис (Service). Web-сервис в целом. В документе WSDL сервис описывается элементом <definitions> в корне дерева. Дочерними являются элементы <types>, <message>, <portType>, <binding>, <service>. У элемента <service> есть атрибут «name», который используется для того, чтобы присвоить имя сервису.
  • Типы (Types). Типы данных, используемые сервисом. В документе WSDL типы данных описываются с помощью элемента <types>, содержащего один или более элементов <xsd:schema>. Для получения дополнительной информации, касающейся описания типов данных, обратитесь по адресу в Интернете: http://www.w3.org/TR/xmlschema-2
  • Сообщение (Message). Абстрактное описание данных, передаваемых или принимаемых сервисом. Допустимо любое количество сообщений. В документе WSDL каждое сообщение описывается элементом <message>. Каждый элемент <message> содержит один или более элементов <part>, необходимых для описания данных по имени и типу.
  • Тип порта (PortType). Абстрактный набор операций, поддерживаемых сервисом. В документе WSDL тип порта описывается элементом <portType>. Каждый элемент <portType> содержит один или более элементов <operation>.
  • Операция (Operation). Абстрактное описание действия, поддерживаемого сервисом. В документе WSDL операция описывается элементом <operation>. Каждый элемент <operation> содержит элементы <input> и <output>, определяющие связанные сообщения. Дополнительные элементы <fault> также могут быть определены.
  • Привязка (Binding). Определение протокола и формата данных, предназначенных для типа порта. В документе WSDL привязка описывается элементом <binding>. У элемента <binding> есть атрибут «type», который определяет название типа порта. Для кодирования SOAP используется элемент <binding>, содержащий элемент <soap:binding> с атрибутами «style» («rpc» или «document») и «transport» («http://schemas.xmlsoap.org/soap/http»). Элемент <binding> содержит элементы <operation>, описывающие формат данных для каждой операции.
  • Порт (Port). Конечная точка, определенная в виде комбинации связывающего и сетевого адресов. В документе WSDL порт описывается элементом <port> под элементом <service>. У элемента <port> есть атрибут «binding», необходимый для присвоения имени связыванию, и атрибут «address location», необходимый для присвоения имени конечной точке сети, связанной с привязкой.

3.2.2 Простой протокол доступа к объектам (SOAP)

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

Из положения консорциума Всемирной паутины (W3C):

«SOAP представляет собой облегченный протокол, предназначенный для обмена структурированной информацией в децентрализованной и распределенной среде. Он основан на протоколе XML, состоящем из трех частей: оболочки, определяющей структуру для описания сообщения и процесса его обработки, набора правил кодирования, служащего для выражения экземпляров типов данных, определенных приложением, и правила, предназначенного для представления удаленных процедурных запросов и ответов».

3.2.3 Импортированный WSDL

В Lotus Domino Designer 7 разработчик приложения может импортировать существующий файл WSDL в приложение и Domino Designer, затем сгенерирует классы на языке LotusScript или Java. Тем не менее, разработчики должны иметь в виду, что не все существующие WSDL-файлы могут быть интерпретированы Lotus Domino Designer 7. Некоторые файлы могут быть отклонены, в зависимости от используемых элементов XML.

3.3 Коммерческие предпосылки использования Web-сервисов

Начиная с Domino Release 5 появилась возможность написания приложений вне сервера Lotus Domino и получения доступа к данным Lotus Domino напрямую. Этого удалось достичь за счет использования привязок COM и CORBA к внутренним классам. Тем не менее, проблема проверки достоверности и согласованности данных, возможно, не была решена соответствующим образом с помощью внешних приложений. Web-сервисы предоставляют хороший компромисс между прямым доступом к данным и возможностью выполнения сетевых операций. Они представляют собой путь раскрытия функций приложений и данных в сети. Разработчики приложений на языке Java, Microsoft .NET, а также многих других могут получить доступ к данным Lotus Domino, просто используя Web-сервисы.

Преимущества приложения, в котором внедрены Web-сервисы, лучше всего продемонстрировать на приложении ITSO Electronics, которое предоставляет клиентам текущую информацию о продуктах. Например, если приложение ITSO Electronics обещает пользователям доступ к информации о продуктах компании ITSO Electronics, ему необходимо разрешить доступ внешних приложений к базе данных покупателей вне зависимости от используемого приложения, будь то Java, J2EE или .NET. В связи с тем, что приложение покупателя отправляет запрос о получении информации Web-сервису, оно должно быть не зависимо от платформы и операционной системы. Элемент Web-сервиса получает запрос о получении данных в виде сообщения XML. Следовательно, если пользователь введет запрос в форму приложения покупателя с целью получения информации о продукте компании ITSO Electronics, Web-сервис получит запрос в виде сообщения SOAP в формате XML и отправит ответ клиенту таким же образом. Используя расширенную поддержку, приложение ITSO Electronics может расширить свою функциональность в целях получения информации о цене продуктов от множества производителей. Используя Java, элемент Web-сервиса может отправлять запросы на получение данных на множество URL-адресов, запрашивая данные о цене, используя протокол XML. Все запросы отправляются в виде сообщений SOAP, и ответы приходят в таком же формате, в приложении ITSO Electronics. Пользователь при этом не знает ни о типе базы данных, из которой получает данные, ни об операционной системе, ни о платформе. Пользователи получают доступ, по-видимому, к неограниченному запасу данных, представленному с особой эффективностью.

3.4 Добавление Web-сервисов к приложению ITSO Electronics

Используя Web-сервисы и поддержку WSDL, вы можете быстро создавать или расширять с их помощью код Java или LotusScript, открывая, таким образом доступ к тысячам приложений Lotus Domino из внешних систем, таких как Java 2 Platform, Enterprise Edition (J2EE) и приложениям Microsoft .NET. В этом разделе мы показываем, как улучшаются приложения ITSO Electronics путем внедрения Web-сервисов в среду разработки приложений Lotus Domino.

Замечание. Web-сервисы могут быть добавлены к любой базе данных Lotus Notes и Domino. Тем не менее, для достижения цели, поставленной в этой книге, все Web-сервисы добавлены к двум отдельным базам данных в приложении ITSO Electronics, которые называются webservices.nsf и wsconsumer.nsf.

3.4.1 Коммерческие предпосылки добавления Web-сервисов к приложению ITSO Electronics

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

3.4.2 Пользовательские требования

Основным пользователем Web-сервисов приложения ITSO Electronics в нашем примере будет клиент фирмы ITSO Electronics. Приложение необходимо для обеспечения доступа пользователя к текущей информации о продукте через программный механизм и пользовательский интерфейс, интуитивный и легкий в использовании.

3.5 Создание простого Web-сервиса в Lotus Domino Designer 7

Позвольте продемонстрировать вам, насколько легко создать Web-сервис с помощью IBM Lotus Domino Designer 7.

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

Необходимо, чтобы приложение ITSO Electronics поддерживало и Java, и LotusScript.

3.5.1 Создание нового Web-сервиса

В этом разделе иллюстрируется создание нового Web-сервиса. В качестве примера используетсяприложение ITSO Electronics:

  1. Откройте базу данных в Domino Designer. В нашем примере мы выбрали базу данных ITSO Web Services. Из списка дизайна выберите Shared Code Þ Web Services (Общий код Þ Web-сервисы), затем щелкните по кнопке New Web Service (Создать Web-сервис). В окне свойств Web-service, в поле Name (Название), введите ProductInfo, таким образом вы присвоите имя Web-сервису. (см. рис. 3.1).

    Рис. 3.1. Окно свойств Web Service
    Рис. 3.1. Окно свойств Web Service

  2. Чтобы создать описание LotusScript, такое же, как на рис. 3.2, вставьте или перепечатайте код, приведенный в примере 3.1, в раздел Web-сервиса Declaration.

    Рис. 3.2. Исходный код для простого Web-сервиса
    Рис. 3.2. Исходный код для простого  Web-сервиса

    Пример 3.1. Код для простого Web-сервиса

    %INCLUDE "lsxsd.lss" Class ProductInfo Function getProductName(productNumber As String, Fault1 As WS_FAULT) As String Dim session  As NotesSession Set session = New NotesSession Dim db As notesdatabase Dim view As notesview Dim doc As notesdocument Set db = session.GetDatabase("","itso/products.nsf") Set view = db.GetView("vaPNumber") Set doc = view.GetDocumentByKey(productNumber, True) If doc Is Nothing Then Call Fault1.setFault(True)   ' необходимо для ошибочной активации Call Fault1.setFaultString("Product " & productnumber & " doesn't exist")  Else getProductName = doc.ProductName(0) End If End Function End Class

  3. Снова откройте окно свойств Web Service и в поле Port type class введите ProductInfo, перед тем как сохранять Web-сервис, так же как на рис. 3.3.

    Рис. 3.3. Окно свойств Web Service: поле PortType class
    Рис. 3.3. Окно свойств Web  Service: поле PortType class

  4. Перейдите к закладке Advanced (Дополнительно) и убедитесь в том, что значение по умолчанию для переключателя Programming model (Программируемая модель) установлено в положение RPC и что значение поля SOAP message format (формат сообщения SOAP) установлено на RPC/encoded (см. рис. 3.4).

    Рис. 3.4. Окно свойств Web Service: закладка Advanced
    Рис. 3.4. Окно свойств Web Service: закладка Advanced

  5. Закройте окно свойств и сохраните Web-сервис.

3.5.2 Просмотр Web-сервиса через браузер

Для того чтобы протестировать новый Web-сервис ProductInfo, откройте браузер и введите следующий URL:
http://servername/databasename.nsf/webservicename?openwebservice (http://имясервера/названиебазыданных.nsf/названиеWeb-сервиса?openwebservice)

В нашем сценарии для приложения ITSO Electronics мы использовали приведенный ниже URL:
http://domino7appdev.cam.itso.ibm.com/itso/webservices.nsf/ProductInfo?openwebservice

Lotus Domino ответит на этот запрос именем порта Web-сервиса и названиями операций для этого порта, а также выведет ссылку на документ WSDL, как показано на рис. 3.5.

Рис. 3.5. Web-сервис, открытый в Web-браузере
Рис. 3.5. Web-сервис, открытый в Web-браузере

3.5.3 Сгенерированный документ WSDL

Приведенная ниже URL-команда Lotus Domino возвращает документ WSDL для Web-сервиса в ответ на HTTP GET, используя суффикс ?WSDL:

http://servername/databasename.nsf/webservicename?WSDL
(http://названиесервера/названиебазыданных.nsf/названиеWeb-сервиса?WSDL)

Например, в нашем сценарии мы использовали следующую команду:

http://domino7appdev.cam.itso.ibm.com/itso/webservices.nsf/ProductInfo?WSDL

В примере 3.2 показан получившийся в результате WSDL-документ.

Для получения более подробного описания документа WSDL см. п. 3.2.1, «Документ WSDL».

Пример 3.2. Код, полученный от сервера при обращении к Web-сервису с суффиксом ?WSDL

  <?xml  version="1.0" encoding="UTF-8"?>
  <wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" 
  xmlns:apachesoap="http://xml.apache.org/xml-soap"
  xmlns:impl="urn:DefaultNamespace" xmlns:intf="urn:DefaultNamespace" 
  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
  xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="urn:DefaultNamespace"> 
  <wsdl:message name="GETPRODUCTNAMERequest"> 
  <wsdl:part name="PRODUCTNUMBER"  type="xsd:string"/> 
  </wsdl:message> 
  <wsdl:message  name="GETPRODUCTNAMEResponse"> 
  <wsdl:part name="GETPRODUCTNAMEReturn"  type="xsd:string"/> 
  </wsdl:message> 
  <wsdl:portType name="ProductInfo"> 
  <wsdl:operation name="GETPRODUCTNAME"  parameterOrder="PRODUCTNUMBER"> 
  <wsdl:input message="impl:GETPRODUCTNAMERequest"  name="GETPRODUCTNAMERequest"/> 
  <wsdl:output message="impl:GETPRODUCTNAMEResponse"  name="GETPRODUCTNAMEResponse"/> 
  </wsdl:operation> 
  </wsdl:portType> 
  <wsdl:binding name="DominoSoapBinding"  type="impl:ProductInfo"> 
  <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> 
  <wsdl:operation  name="GETPRODUCTNAME"> 
  <wsdlsoap:operation  soapAction=""/> 
  <wsdl:input  name="GETPRODUCTNAMERequest"> 
  <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  namespace="urn:DefaultNamespace" 
  use="encoded"/> 
  </wsdl:input> 
  <wsdl:output  name="GETPRODUCTNAMEResponse"> 
  <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  namespace="urn:DefaultNamespace" 
  use="encoded"/> 
  </wsdl:output> 
  </wsdl:operation> 
  </wsdl:binding> 
  <wsdl:service name="ProductInfoService"> 
  <wsdl:port  binding="impl:DominoSoapBinding" name="Domino"> 
  <wsdlsoap:
  address location=
  "http://domino7appdev.cam.itso.ibm.com:
  80/itso/webservices.nsf/ProductInfo?OpenWebService"/> 
  </wsdl:port> 
  </wsdl:service> 
  </wsdl:definitions>

Полученный в результате генерации с суффиксом ?WSDL код сложен, однако это не важно, так как документы WSDL считываются компьютерами, а не пользователями. Например, Lotus Domino Designer может импортировать документ WSDL и создать каркасный класс в LotusScript или Java. Обсуждением данной темы мы занимались в п. 3.2.3, «Импортированный WSDL».

3.5.4 Тестирование простого Web-сервиса

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

  • Запустите Rational Application Developer.
  • Выберите Run - Launch the Web Services Explorer (Выполнить - Запустить обозреватель Web-сервисов).
  • Щелкните по иконке WSDL page (вторая справа, находится в верхней правой части основного окна).
  • Затем перейдите к панели Navigator (Навигатор) и выберите WSDL Main (Основной WSDL), как показано на рис. 3.6.

    Рис. 3.6. Выберите WSDL Main на панели Navigator
    Рис. 3.6. Выберите WSDL Main на панели Navigator

  • Перейдите к панели Open WSDL, после чего определите WSDL URL. В нашем приложении ITSO Electronics мы использовали следующий URL: http://domino7appdev.cam.itso.ibm.com/itso/webservices.nsf/ProductInfo?wsdl
  • Щелкните по кнопке Go (Перейти), после чего откроется панель WSDL Binding Details (Детали привязки WSDL), которая представлена на рис. 3.7.

    Рис. 3.7. Панель WSDL Binding Details
    Рис. 3.7. Панель WSDL Binding Details

  • В панели WSDL Binding Details показаны операции, производимые для элемента SOAP. Выберите операцию, указанную в панели, чтобы записать ее параметры и задействовать ее или же определить большее количество конечных точек. В этом сценарии (сценарии компании ITSO Electronics) выберите операцию GETPRODUCTNAME (Получить название продукта), после чего появится панель Invoke a WSDL Operation (Задействовать операцию WSDL), как показано на рис. 3.8.

    Рис. 3.8. Панель Invoke a WSDL Operation
    Рис. 3.8.  Панель Invoke  a WSDL Operation

  • Введем значение PRODUCTNUMBER и щелкнем по кнопке Go. Результат появился в панели Status (Статус). В нашем сценарии в качестве PRODUCTNUMBER (номера продукта) мы ввели значение 45000 и получили результирующую строчку Redbook Basic (см. рис. 3.9).

    Рис. 3.9. Панель Invoke a WSDL Operation Status
    Рис. 3.9.  Панель Invoke  a WSDL Operation Status

  • Чтобы увидеть, что же на самом деле происходит за кулисами, щелкните по кнопке Source (Источник), находящейся на панели Status. В примере 3.3 приведен код, отправленный на сервер Lotus Domino в контексте запроса SOAP. Код, которым сервер Lotus Domino ответил отправлением контекста ответа SOAP на этот запрос, представлен в примере 3.4, после чего этот код был представлен в панели Status, как и видно из рис. 3.10.
    Пример 3.3. Контекст запроса SOAP

    <?xml version="1.0" encoding="UTF-8" ?> - <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <SOAP-ENV:Body> - <ns0:GETPRODUCTNAME xmlns:ns0="urn:DefaultNamespace" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <PRODUCTNUMBER xsi:type="xsd:string">45000</PRODUCTNUMBER> </ns0:GETPRODUCTNAME> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

    Пример 3.4. Контекст ответа SOAP, отправленный обратно с сервера

    soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <soapenv:Body> - <ns1:GETPRODUCTNAMEResponse xmlns:ns1="urn:DefaultNamespace" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <GETPRODUCTNAMEReturn xsi:type="xsd:string">Redbook Basic</GETPRODUCTNAMEReturn> </ns1:GETPRODUCTNAMEResponse> </soapenv:Body> </soapenv:Envelope>

    Рис. 3.10. Исходный код, представленный в панели Status
    Рис. 3.10. Исходный код, представленный в  панели Status

  • Наконец, чтобы увидеть разницу в формате XML, вернитесь в Lotus Domino Designer и измените формат сообщения SOAP на Wrapped в окне свойств Advanced, как показано на рис. 3.11. Снова задействуйте Web-сервис GETPRODUCTNAME из Rational Application Developer. Результат будет таким же, как в примерах 3.5 и 3.6.

    Рис. 3.11. Формат сообщения SOAP установленный на Wrapped
    Рис. 3.11. Формат сообщения SOAP установленный на Wrapped

    Пример 3.5. Контекст запроса SOAP, в котором использован формат сообщения SOAP Wrapped

    <?xml version="1.0" encoding="UTF-8" ?> - <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="urn:DefaultNamespace" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <SOAP-ENV:Body> - <q0:GETPRODUCTNAME> <PRODUCTNUMBER>45000</PRODUCTNUMBER> </q0:GETPRODUCTNAME> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

    Пример3.6. Контекст ответа SOAP, в котором использован формат сообщения SOAP Wrapped

    - <soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <soapenv:Body> - <ns1:GETPRODUCTNAMEResponse xmlns:ns1="urn:DefaultNamespace"> <GETPRODUCTNAMEReturn>Redbook Basic</GETPRODUCTNAMEReturn> </ns1:GETPRODUCTNAMEResponse> </soapenv:Body> </soapenv:Envelope>

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

 

3.6 Создание сложного Web-сервиса в Lotus Domino Designer 7

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

Для предоставления покупателям права доступа к информации о продуктах нам необходимо предоставить на совместное использование следующую информацию о продукте:

  • Название продукта (Product name).
  • Цена (Price).
  • Номер (Number).
  • Описание (Description).

В примере 3.7 приведены данные объекта Product. Этот объект будет использован в качестве сложного типа данных в Web-сервисе, над созданием которого мы будем работать в п. 3.5.1. В данном примере использован язык программирования Java.

Пример3.7. Код Product.java

  public class Product 
  {
  private String name;
  private int number;
  private String  description;
  private double price;
  public String getName(){  return name; }
  public int getNumber(){  return number; }
  public double  getPrice(){ return price; }
  public String  getDescription() { return description; }
  public void  setName(String newName)
  {
  name = newName;
  }
  public void  setNumber(int newNumber)
  {
  number = newNumber;
  }
  public void  setDescription(String newDescription)
  {
  description =  newDescription;
  }
  public void  setPrice(double newPrice)
  {
  price = newPrice;
  } 
  }

В п. 3.5.1, «Создание нового Web-сервиса», мы создавали Web-сервис, используя примитивный тип данных. В этом примере мы предпримем те же действия для создания Web-сервиса для объекта Product, который позволит обеспечить партнеров подробной информацией о продуктах. В приведенных ниже действиях обобщается способ создания Web-сервиса.

  • Откройте базу данных ITSO Web Services в Domino Designer, затем Shared Code - Web Services (Общий код - Web-сервисы). Щелкните по кнопке New Web Service (Создать Web-сервис).
  • В окне свойств Web-service, в поле Name, введите ProductService, таким образом вы присвоите имя своему Web-сервису. В качестве класса PortType используйте ProductService.
  • В панели Options переключитесь на Java.
  • Щелкните по кнопке New Class (Создать класс), после чего замените код предоставляемым по умолчанию кодом, представленным в примере 3.8. Этот код называется ProductService.java.
  • Снова щелкните по кнопке New Class и вставьте код из примера 3.7. Этот код называется Product.java.
  • Сохраните Web-сервис.

Пример3.8. ProductService.java

  import lotus.domino.*;
  import  lotus.domino.types.*;
  import java.util.*;
  public class  ProductService 
  { 
  private Session session  = WebServiceBase.getCurrentSession(); 
  public Object[] getAllProducts()
  {
  Product[] result = null;
  Database db = null;
  View view = null;
  Product product = null;
  ArrayList tempList = new ArrayList();
  try
  {
  db = getProductDb();
  view =  db.getView("vaPNumber");
  Document doc2, doc = view.getFirstDocument();
  while(doc != null)
  {
  product = getProductFromDocument(doc);
  tempList.add(product);
  doc2 = doc;
  doc =  view.getNextDocument(doc);
  doc2.recycle();
  }
  view.recycle();
  db.recycle();  
  }catch(NotesException  e){e.printStackTrace();} 
  return  tempList.toArray(); 
  }
  private Product  getProductFromDocument(Document doc)
  {
  Product product = null; 
  try
  {
  String name =  doc.getItemValueString("ProductName");
  String description =  doc.getItemValueString("ProductDescription");
  double price =  doc.getItemValueDouble("ProductPrice");
  int productNumber = doc.getItemValueInteger("productNumber");
  product = new Product(); 
  product.setNumber(productNumber);
  product.setName(name);
  product.setPrice(price);
  product.setDescription(description);
  }
  catch(Exception e)
  {}
  return product;
  }
  private Database  getProductDb()
  {
  Database db = null;
  try{
  db =  session.getDatabase("","itso\\products.nsf");
  }catch(NotesException  e){}
  return db;
  }
  public Product  getProduct(double productNumber)
  {
  Product product = null;
  try
  {
  Database db = getProductDb();
  View view = db.getView("vaPNumber");
  Document doc = view.getDocumentByKey(new Double(productNumber),  true); 
  if(doc != null)
  {
  product =  getProductFromDocument(doc);
  doc.recycle();
  doc = null;
  }
  view.recycle();
  db.recycle();  
  }catch(NotesException e){} 
  return product;
  }
  }

Мы можем использовать новый Web-сервис, названный ProductService из Rational Application Developer, как показано на рис. 3.12.

Рис. 3.12. Исполнение операции WSDL getProduct
Рис. 3.12. Исполнение операции WSDL getProduct

Пример 3.9 выводит контекст ответа SOAP, полученный от сервера Lotus Domino для определенного номера продукта, который мы использовали для активирования операции WSDL getProduct.

Пример 3.9. Контекст ответа SOAP, полученный от сервера

  <soapenv:Envelope  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  - <soapenv:Body>
  -  <ns1:getProductResponse xmlns:ns1="urn:DefaultNamespace" 
  soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <getProductReturn href="#id0" /> 
  </ns1:getProductResponse>
  - <multiRef  xmlns:ns2="urn:DefaultNamespace" 
  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"  id="id0" soapenc:root="0" 
  soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
   xsi:type="ns2:Product">
  <description  xsi:type="xsd:string">This is the basic Redbook offering.</description> 
  <name xsi:type="xsd:string">Basic  Redbook</name> 
  <number  xsi:type="xsd:int">20501</number> 
  <price  xsi:type=«"xsd:double">102.0</price> 
  </multiRef>
  </soapenv:Body>
  </soapenv:Envelope>

У Web-сервиса ProductService, который мы только что создали, есть и другая операция, отправляющая набор объектов продуктов в виде массива, которая называется getAllProducts. Пример 3.10 наглядно иллюстрирует этот процесс.  Его сообщения SOAP имеют формат: RPC/encoded.

Пример 3.10. Контекст ответа SOAP

  - <soapenv:Envelope  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  - <soapenv:Body>
  - <ns1:getAllProductsResponse  xmlns:ns1="urn:DefaultNamespace" 
  soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  -  <getAllProductsReturn  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
  soapenc:arrayType="xsd:anyType[9]"  xsi:type="soapenc:Array">
  <item href="#id0" /> 
  <item href="#id1" /> 
  <item href="#id2" /> 
  <item href="#id3" /> 
  <item href="#id4" /> 
  <item href="#id5" /> 
  <item href="#id6" /> 
  <item href="#id7" /> 
  <item href="#id8" /> 
  </getAllProductsReturn>
  </ns1:getAllProductsResponse>
  - <multiRef  xmlns:ns2="urn:DefaultNamespace" 
  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"  id="id1" soapenc:root="0" 
  soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"  
  xsi:type="ns2:Product">
  <description  xsi:type="xsd:string">Redpaper mid-tier line available at newsagents and 
  department  stores.</description> 
  <name xsi:type="xsd:string">Redpaper  Deluxe</name> 
  <number  xsi:type="xsd:int">10002</number> 
  <price  xsi:type="xsd:double">2299.0</price> 
  </multiRef>
  - <multiRef  xmlns:ns3="urn:DefaultNamespace" 
  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"  id="id8" soapenc:root="0" 
  soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"  
  xsi:type="ns3:Product">
  <description xsi:type="xsd:string">The  best Redbook money can buy.</description> 
  <name xsi:type="xsd:string">Redbook  Plus</name> 
  <number  xsi:type="xsd:int">45500</number> 
  <price  xsi:type="xsd:double">50000.0</price> 
  </multiRef>
  и так далее.......
  - <multiRef  xmlns:ns10="urn:DefaultNamespace" 
  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"  id="id6" soapenc:root="0" 
  soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"  
  xsi:type="ns10:Product">
  <description xsi:type="xsd:string">The  ultimate Redbook experience.</description> 
  <name xsi:type="xsd:string">Redbook  Supreme</name> 
  <number  xsi:type="xsd:int">20564</number> 
  <price  xsi:type="xsd:double">1000.0</price> 
  </multiRef>
  </soapenv:Body>
  </soapenv:Envelope>

3.7 Экспортирование документа WSDL

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

  • Откройте базу данных ITSO Web Services в Domino Designer и выберите Shared Code - Web Services (Общий код - Web-сервисы).
  • Выберите ProductService и щелкните по кнопке Export WSDL (Экспортировать документ WSDL).
  • После этого будет сгенерирован файл WSDL в формате XML. В нашем сценарии мы использовали расширение .wsdl для того, чтобы опознать экспортированный файл WSDL, как видно из рис. 3.13.

    Рис. 3.13. Экспортирование документа WSDL
    Рис. 3.13. Экспортирование  документа WSDL

3.8 Импортирование документа WSDL

Если вы импортируете документ WSDL, описательный класс генерируется на основе содержания документа WSDL. Общедоступные прототипы методов, функций и подстановок в классе соответствуют операциям Web-сервиса, определенным для первого элемента <port> первого элемента <service> в документе WSDL. Другие классы или типы ссылаются на прототипы методов, которые, возможно, также будут сгенерированы на основании содержимого документа WSDL вместе с общедоступными элементами данных. Если вы измените прототип интерфейса, соответствующий документ WSDL также изменится, когда Web-сервис будет сохранен. Вы можете отслеживать подобные изменения с помощью свойства «Warn if the WSDL interface is modified» (Предупреждать, если интерфейс WSDL был изменен).

Бизнес-партнеры компании ITSO Electronics, а также возможные покупатели, в свою очередь, могут обеспечивать компанию документом WSDL, который она может использовать для создания Web-сервисов. Вы можете импортировать существующий документ WSDL, чтобы сгенерировать каркас Web-сервиса. Каркасный код соответствует описанию Web-сервиса. Затем вам необходимо добавить код реализации.

Для того чтобы импортировать документ WSDL, выполните следующее:

  • Откройте базу данных ITSO Web Services в Domino Designer, затем выберите Shared Code - Web Services.
  • Щелкните по кнопке Import WSDL и выберите файл WSDL, который хотите импортировать. В нашем сценарии мы импортировали файл, который экспортировали в предыдущем разделе (см. рис. 3.14).

    Рис. 3.14. Импортирование документа WSDL
    Рис. 3.14. Импортирование документа WSDL

  • В результате импортирования документа WSDL будет сгенерирован каркасный код, который в нашем сценарии сгенерирован на языке LotusScript, как показано в примере 3.11. Затем мы открыли окно свойств Web Service, поставили галочку рядом с опцией Warn if the WSDL interface is modified (рис. 3.15).

    Рис. 3.15. Импортирование документа WSDL: окно свойств Web Service
    Рис. 3.15. Импортирование документа WSDL: окно свойств Web Service

    Пример3.11. Каркасный код, сгенерированный после импортирования документа WSDL

    %INCLUDE "lsxsd.lss" Class ArrayOfProduct_Holder As INOUT_HOLDER Public Value() As Product End Class Class Product Public description As XSD_STRING Public name As XSD_STRING Public number As Long Public price As Double Sub NEW End Sub End Class Class ProductService Sub NEW End Sub Function getAllProducts() As ArrayOfProduct_Holder End Function Function getProduct(productNumber As Double) As Product End Function End Class

3.9 Работа с исключениями и ошибками в Web-сервисах

Операции также могут возвращать ошибки посредством подкласса ошибок, который соответствует некоторому сообщению <wsdl:fault>, выбранному для определенной операции в документе WSDL, или посредством прямого использования базового класса WS_FAULT (LotusScript), или класса lotus.domino.types.Fault, или класса java.lang.Exception (Java).

Замечание. Любые ошибки в методе описания сервиса на языке LotusScript (т. е. любой основной класс или подкласс WS_FAULT) должны фигурировать в конце списка параметров метода.

Ошибки для метода описания сервиса на языке Java возникают в стандартных предложениях Java.

Для получения дополнительной информации о том, как работать с ошибками, используя язык LotusScript см. п. 3.12, «Использование Web-сервисов с помощью LS2J».

3.10 Безопасность в Web-сервисах

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

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

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

В архитектуре приложения ITSO Electronics существует три фундаментальных принципа, относящихся к безопасности: ресурсы, которые должны быть защищены; механизмы, благодаря которым обеспечивается эта защита (т. е. политика защиты); и политики, которые представляют собой обрабатываемые компьютерами  документы, которые, описывают ограничения на этих ресурсах. Для продолжения дискуссии о безопасности применения Web-сервисов обратитесь к руководству Web Service Architecture, которое доступно по следующему адресу в Интернете:
http://www.w3.org/TR/2004/NOTE-ws-arch-20040211

Web-сервис Lotus Domino 7 обладает теми же возможностями защиты, что и агент. Уровень защиты Web-сервиса устанавливается в закладке Security (Безопасность) окна свойств Web service. В приведенном ниже списке описываются параметры, доступные в закладке Security.

  • Run as web user (Запускать от лица Web-пользователя): код Java или LotusScript запускается с реальным именем пользователя, который запустил Web-сервис.
  • Run on behalf of (Запускать от лица): код Java или LotusScript запускается на полномочиях определенного пользователя. Тем не менее, подписчик Web-сервиса должен обладать неограниченными правами на сервер или же обладать правом запускать Web-сервисы от лица любого пользователя.
  • Set runtime security level (Установить уровень защиты выполнения) (один из перечисленных ниже):
    • Do not allow restricted operations (Не разрешать выполнение операций с ограниченным доступом);
    • Allow restricted operations (Разрешать выполнение операций с ограниченным доступом);
    • Allow restricted operations with full administration rights (Разрешать выполнение операций с ограниченным доступом и полными правами администрирования).
  • Default access for this web service (Доступ по умолчанию к этому Web-сервису):
    • All readers and above (Все читатели и выше). Вы можете выбрать или снять этот параметр.
    • Enumerated (Перечисленные). Если вы убрали галочку рядом с параметром All readers and above, то с помощью этого параметра вы можете выбрать тех, кому вы хотите предоставить доступ по умолчанию.
  • Allow Public Access users to use this web service (Разрешить пользователям открытого доступа применять этот Web-сервис). Если выбран этот параметр, пользователи, обладающие открытым доступом к документам в базе данных, получают доступ по умолчанию.

3.11 Применение Web-сервисов, использующих Java

На момент написания этой книги Lotus Domino 7.0 обеспечивал, хотя и не в полном объеме, использование Web-сервисов. Тем не менее, вспомогательным бизнес-требованием, предъявляемым к приложению ITSO Electronics, является предоставление доступа к ценовым данным, располагающимся за границами Lotus Domino, что, в свою очередь, диктует необходимость применения Web-сервисов в этом приложении. В нашем сценарии компания ITSO Electronics решила применить программный продукт с открытым исходным кодом Apache SOAP, чтобы использовать Web-сервисы с помощью Java. Apache SOAP представляет собой внедрение представления SOAP в W3C. Он базируется и заменяет собой разработку IBM SOAP4J. Последующий, улучшенный проект Apache Axis доступен по следующему адресу в Интернете:
http://ws.apache.org/axis/

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

Замечание. Web-сервисы могут быть добавлены к любой базе данных Lotus Notes и Domino. Но для достижения целей, поставленных в этой книге, все Web-сервисы добавлены к отдельным базам данных в приложении ITSO Electronics, которые называются webservices.nsf и wsconsumer.nsf.

Приведенная ниже последовательность действий наглядно иллюстрирует создание агента, использующего Web-сервис.

  1. Загрузите самую последнюю версию Apache SOAP по следующей ссылке:
    http://ws.apache.org/soap/
  2. Извлеките загруженный файл во временную директорию, в нашем сценарии в качестве такой папки мы использовали папку c:\soap.
  3. Экспортируйте сложный Web-сервис ProductService (находящийся в базе данных Web Services) в документ WSDL. В экспортированном документе WSDL содержится вся информация, необходимая для использования Web-сервиса.
  4. Откройте документ WSDL в текстовом редакторе. Документ WSDL содержит информацию, описывающую сложный тип данных, возвращаемых этим Web-сервисом, как видно из примера 3.12. В нашем случае этот сложный тип данных называется Product. Сложный элемент Type показывает свойства объекта Product, к которым относятся описание, название, номер и цена.
    Пример 3.12. Тип WSDL для Product

    <wsdl:types> <schema targetNamespace="urn:DefaultNamespace" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/> <complexType name="Product"> <sequence> <element name="description" nillable="true" type="xsd:string"/> <element name="name" nillable="true" type="xsd:string"/> <element name="number" type="xsd:int"/> <element name="price" type="xsd:double"/> </sequence> </complexType> <complexType name="ArrayOfProduct"> <complexContent> <restriction base="soapenc:Array"> <attribute ref="soapenc:arrayType" wsdl:arrayType="impl:Product[]"/> </restriction> </complexContent> </complexType> </schema> </wsdl:types>

  5. Откройте новую базу данных WS Consumer в Domino Designer, выберите Shared Code - Agents (Общий код - Агенты), после чего щелкните по кнопке New agent (Создать агент).
  6. В поле Name окна свойств Agent введите ConsumeWS и в разделе Runtime в выпадающем меню Target (Цель) выберите None (Отсутствует), как показано на рис. 3.16.

    Рис. 3.16. Окно свойств ConsumerWS Agent
    Рис. 3.16.  Окно свойств ConsumerWS Agent

  7. Закройте окно свойств Agent, затем выберите язык кода Java.
  8. Нам необходимо создать класс JavaBean, представляющий сложный тип данных Product, определенный в документе WSDL. Для облегчения этой операции мы воспользуемся преимуществами импортирования функциональности WSDL для автоматической генерации класса JavaBean. После этого нам необходимо вернуться к списку разработки, выбрать Shared Code - Web Service (Общий код - Web-сервис) и щелкнуть по кнопке New Web Service (Создать Web-сервис).
  9. Закройте окно Web Service и убедитесь в том, что язык описания Web-сервиса установлен на Java. Щелкните по кнопке Import WSDL (Импортировать WSDL), затем выберите созданный ранее документ WSDL. В результате импортирования этого документа будут автоматически созданы классы JavaBeansTM.
  10. Выделите и скопируйте код Java для Product.java.
  11. Вернитесь к агенту и щелкните по кнопке New Class (Создать класс). Затем замените класс Untitled.java скопированным кодом Product.java, так же, как это сделано в примере 3.13.
  12. Сохраните агент ConsumeWS и убедитесь в том, что он был успешно скомпилирован. Щелкните по кнопке Edit Project (Изменить проект), после чего откроется окно Java Agent Files (см. рис. 3.17). Перейдите к нужной директории библиотеки SOAP LIB, в нашем случае эта директория находилась по следующему пути: c:\soap\soap-2_3_1\lib. В качестве типа файла выберите Archive (Архивный), щелкните по кнопке Add/Replace File(s) (Добавить/Заменить файлы) и щелкните по кнопке ОК.

    Рис. 3.17. Окно Organize Java Agent Files
    Рис. 3.17.  Окно Organize  Java Agent Files

  13. Вам необходимо заменить код по умолчанию, JavaAgent.java, своим собственным, чтобы приступить к использованию Web-сервиса, который в нашем сценарии представлен в примере 3.14. Убедитесь в том, что в классе JavaAgent.java есть переменные URL и soapAction. Эти переменные должны указывать на расположение вашего приложения.
  14. Сохраните агент ConsumeWS.
  15. Вернитесь к новому Web-сервису и закройте его, не осуществляя предварительного сохранения.
  16. Откройте клиент Lotus Notes и выберите базу данных WS Consumer. Перейдите к Actions - ConsumeWS (Действия - ConsumeWS) для того, чтобы запустить только что созданный агент. Агент отобразит набор объектов Product, используемых в Web-сервисе, в окне Java, как видно на рис. 3.18.

    Рис. 3.18. Окно Java, в котором отображен результат работы Web-сервиса
    Рис. 3.18. Окно Java, в котором отображен  результат работы Web-сервиса

    Если окно не открылось, выберите File - Tools - Show Java Debug Console (Файл - Сервис - Показать консоль отладки Java) для получения дополнительной информации.
    Пример 3.13. Код класса Product

    public class Product  { private java.lang.String description; private java.lang.String name; private int number; private double price; public Product() { } public java.lang.String getDescription() { return description; } public void setDescription(java.lang.String description) this.description = description; } public java.lang.String getName() { return name; } public void setName(java.lang.String name) { this.name = name; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } private java.lang.Object __equalsCalc = null; public synchronized boolean equals(java.lang.Object obj) { if (!(obj instanceof Product)) return false; Product other = (Product) obj; if (obj == null) return false; if (this == obj) return true; if (__equalsCalc != null) { return (__equalsCalc == obj); } __equalsCalc = obj; boolean _equals; _equals = true & ((this.description==null & other.getDescription()==null) / (this.description!=null & this.description.equals(other.getDescription()))) & ((this.name==null & other.getName()==null) // (this.name!=null & this.name.equals(other.getName()))) & this.number == other.getNumber() & this.price == other.getPrice(); __equalsCalc = null; return _equals; } private boolean __hashCodeCalc = false; public synchronized int hashCode() { if (__hashCodeCalc) { return 0; } __hashCodeCalc = true; int _hashCode = 1; if (getDescription() != null) { _hashCode += getDescription().hashCode(); } if (getName() != null) { _hashCode += getName().hashCode(); } _hashCode += getNumber(); _hashCode += new Double(getPrice()).hashCode(); __hashCodeCalc = false; return _hashCode; } }

    Пример 3.14. Код, необходимый для применения Web-сервиса, использующего Java

    import lotus.domino.*; import java.io.*; import java.util.*; import java.net.*; import org.w3c.dom.*; import org.apache.soap.util.xml.*; import org.apache.soap.*; import org.apache.soap.encoding.*; import org.apache.soap.encoding.soapenc.*; import org.apache.soap.rpc.*; import javax.swing.*; public class JavaAgent extends AgentBase { public void NotesMain() { try { Session session = getSession(); AgentContext agentContext = session.getAgentContext(); URL url = new URL("http://domino7appdev.cam.itso.ibm.com/itso/webservices.nsf/ProductService?WSDL"); String soapAction ="http://domino7appdev.cam.itso.ibm.com/itso/webservices.nsf/ProductService?WSDL"; Call call = new Call(); BeanSerializer beanSerializer = new BeanSerializer(); SOAPMappingRegistry smRegistry = new SOAPMappingRegistry(); smRegistry.mapTypes(Constants.NS_URI_SOAP_ENC, new QName( "urn:DefaultNamespace", "Product"), Product.class, beanSerializer, beanSerializer); String targetNamespace = "urn:DefaultNamespace"; call.setSOAPMappingRegistry(smRegistry); call.setTargetObjectURI(targetNamespace); call.setMethodName("getAllProducts"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); Response resp = null; try { resp = call.invoke(url, soapAction); } catch (SOAPException e) { e.printStackTrace(); System.err.println("SOAP Exception code: " + e.getFaultCode() + " message: " + e.ge return; } if (!resp.generatedFault()) { Parameter ret = resp.getReturnValue(); Product[] products = (Product[]) ret.getValue(); buildGUI(products); } else { Fault fault = resp.getFault(); System.err.println("SOAP Fault,  " + fault.getFaultCode() + "   " + fault.getFaultS } } catch (Exception e) { e.printStackTrace(); } } private void buildGUI(Product[] products) { StringBuffer sb = new StringBuffer(); String newLine = "<br>"; for(int i = 0; i  < products.length; i++) { sb.append(newLine + newLine); sb.append(products[i].getName() + « (« + products[i].getNumber() + «)» + newLine); sb.append( " * " + products[i].getDescription()); sb.append(newLine + " * " + products[i].getPrice()); } JFrame frame = new JFrame("Web service content"); frame.getContentPane().add(new JScrollPane(new JLabel("<html>" + sb.toString() + "</html>"))); frame.pack(); frame.setVisible(true); } }

3.12 Использование Web-сервисов, применяющих LS2J

В этом разделе мы расскажем о следующем:

  • как применять Web-сервис, использующий LotusScript;
  • как с помощью LS2J обращаться к коду Java из агента LotusScript;
  • как работать с исключениями или ошибками, отправляемыми назад от Web-сервиса;
  • об аутентификации и Web-сервисах.

3.12.1 Несколько слов о LS2J

LS2J представляет собой интерфейс, позволяющий пересылать тип данных Java в тип данных LotusScript, а также позволяет LotusScript выполнять объектные методы Java. Благодаря LS2J LotusScript получает способность создавать объекты Java так, будто они были родными для среды LotusScript.

В этом сценарии мы добавили агент LotusScript к базе данных WS Consumer. Агент использует код Java из библиотеки скриптов, для того чтобы использовать Web-сервис.

Web-сервис, который мы используем, способен выполнять одно из двух действий:

  • возвращать имя текущего пользователя;
  • возвращать объект WS_FAULT, для того чтобы проиллюстрировать, как Web-сервисы способны отправлять коды ошибок обратно к клиенту.

3.12.2 Создание Web-сервиса

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

  1. Откройте базу данных Web Services в Domino Designer.
  2. Щелкните по кнопке New Web Service.
  3. Убедитесь, что установлен язык кода LotusScript.
  4. Перейдите к разделу Declarations и перепечатайте код, представленный в примере 3.15.
    Пример 3.15. Код LS2J Web Service

    Dim session As NotesSession Class UserInfo Function getUserName ( Fault1 As WS_FAULT) Set session = New NotesSession Dim doc As NotesDocument Set doc = session.DocumentContext If  Cint(Rnd() * 10) > 5 Then getUserName =  doc.remote_user(0) Else Call Fault1.setFault(True)   ' необходимо для ошибочной активации Call Fault1.setFaultString("SUCCESS, We send a FAULT on purpose")                           End If End Function         End Class

  5. Откройте окно свойств Web-сервиса и в поле Name и PortType введите UserInfo, как показано на рис. 3.19.

    Рис. 3.19. Окно свойств LS2J Web Service UserInfo
    Рис. 3.19. Окно свойств LS2J Web Service  UserInfo

  6. Сохраните и закройте Web-сервис.

3.12.3 Создание библиотеки скриптов, необходимой для использования Web-сервиса с помощью Java

Теперь нам необходимо создать библиотеку скриптов, содержащую класс Java, который будет использовать Web-сервис и сделает его доступным нашему агенту LotusScript через LS2J. Для того чтобы настроить класс Java, необходимо выполнить следующую последовательность действий:

  • Откройте базу данных WS Consumer в Domino Designer.
  • В навигационной панели выберите Shared Code (Общий код) и щелкните по кнопке New Java Library (Новая библиотека Java).
  • В открывшемся окне щелкните по кнопке Edit Project и выберите файл Apache soap.jar (см. рис. 3.20). Если у вас отсутствует файл Apache soap.jar, необходимо вернуться к п. 3.11, «Применение Web-сервисов, использующих Java» для получения дополнительной информации о том, как загрузить Apache SOAP.

    Рис. 3.20. Импортирование архива Java, который будет использован с LS2J
    Рис. 3.20. Импортирование архива Java, который будет  использован с LS2J

  • Сохраните библиотеку скриптов под именем ConsumeWSLibrary.
  • Замените код для библиотеки по умолчанию кодом, приведенным в примере 3.16.

Важно. Приведенные ниже строчки из примера 3.16 должны быть скорректированы и соответствовать URL вашей базы данных:
URL url = new URL("http://domino7appdev.cam.itso.ibm.com/itso/webservices.nsf/ProductService?WSDL");
String soapAction ="http://domino7appdev.cam.itso.ibm.com/itso/webservices.nsf/ProductService?WSDL";

Пример 3.16. Код Java, необходимый для использования Web-сервисов средой LS2J

  import java.io.*;  
  import java.util.*;
  import java.net.*;
  import org.w3c.dom.*;
  import  org.apache.soap.util.xml.*;
  import  org.apache.soap.*;
  import  org.apache.soap.encoding.*;
  import org.apache.soap.encoding.soapenc.*;
  import  org.apache.soap.rpc.*;
  import  org.apache.soap.transport.http.SOAPHTTPConnection;
  public class WSConsumer
  {
  public String getValue(String userName,  String password)
  {
  try
  {
  URL url = 
  new  URL("http://domino7appdev.cam.itso.ibm.com/itso/webservices.nsf/UserInfo?WSDL");
  String soapAction  =
  "http://domino7appdev.cam.itso.ibm.com/itso/webservices.nsf/UserInfo?WSDL";
  Call call = new Call();
  SOAPHTTPConnection hc = new  SOAPHTTPConnection();
  hc.setUserName(userName);
  hc.setPassword(password);
  call.setSOAPTransport(hc);
  SOAPMappingRegistry smRegistry =  new SOAPMappingRegistry();
  String targetNamespace =  "urn:DefaultNamespace";
  call.setSOAPMappingRegistry(smRegistry);
  call.setTargetObjectURI(targetNamespace);
  call.setMethodName("getUserName");
  call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
  Response resp = null;
  try
  {
  resp = call.invoke(url,  soapAction);
  } catch (SOAPException e)
  {
  e.printStackTrace();
  return ("SOAP Exception code:  " + e.getFaultCode() + " message: " + e.getMessage());
  }
  if (!resp.generatedFault())
  {
  Parameter ret =  resp.getReturnValue();
  return ret.getValue() +  ««;                
  } 
  else
  {
  Fault fault = resp.getFault();
  return ("SOAP Fault,  " + fault.getFaultCode() + "   " + fault.getFaultString());
  }
  } catch (Exception e)
  {
  e.printStackTrace();
  }
  return null;
  }
}

3.12.4 Создание агента, используя язык LotusScript

Наконец нам необходимо создать агент LotusScript и использовать только что созданную библиотеку через LS2J.

  • В панели Navigation выберите Shared Code - Agents.
  • Щелкните по кнопке New Agent. В окне свойств нового агента, в поле Name, введите LotusScriptConsumeWS, а в выпадающем списке Target раздела Runtime выберите None. Закройте окно свойств.
  • Измените язык на LotusScript.
  • В Declarations замените код по умолчанию кодом, приведенным в примере 3.17.
  • В Initialize замените код по умолчанию кодом из примера 3.18.
    Замечание. Скорректируйте строчку value = myObject.getValue("The UserName", "The Password"), введя правильное имя пользователя и пароль.
    Пример 3.17. Код Declaration для агента LotusScript LS2J

    Option Public Use "ConsumeWSLibrary" Uselsx "*javacon"

    Пример 3.18. Код Initialize для агента LotusScript LS2J

    Sub Initialize Dim mySession As JavaSession Dim myClass As JavaClass Dim myObject As JavaObject Set mySession = New JavaSession () Set myClass = mySession.GetClass("WSConsumer") Set myObject = myClass.CreateObject Dim value As String value = myObject.getValue("The UserName", "The Password") Msgbox value End Sub

  • Сохраните и закройте агент.
  • В клиенте Lotus Notes запустите только что созданный агент. Если вы увидите сообщение, которое представлено на рис. 3.21, то оно, скорее всего, вызвано тем, что вы не обеспечили код точным именем пользователя и паролем.

    Рис. 3.21. Сообщение об ошибке, возникшей при использовании Web-сервиса с помощью LS2J
    Рис. 3.21. Сообщение об ошибке, возникшей  при использовании Web-сервиса с помощью LS2J

    Если агент смог использовать ваш Web-сервис, вы увидите сообщение, представленное на рис. 3.22.

    Рис. 3.22. Web-сервис был успешно использован с помощью LS2J
    Рис. 3.22. Web-сервис был  успешно использован с помощью LS2J

3.12.5 Аутентификация и Web-сервисы

В Lotus Notes и Domino 7 Web-сервис обладает теми же возможностями защиты, что и агент. В примере 3.19 мы использовали базовую аутентификацию HTTP, для того чтобы защитить наш Web-сервис. Apache SOAP позволяет нам отправлять имена пользователей и пароли в виде SOAP-запросов, добавляя экземпляр класса SOAPHTTPConnection к объекту Call.

Пример 3.19. Базовая аутентификация с помощью Apache SOAP

Call call = new Call(); 
  SOAPHTTPConnection hc =  new SOAPHTTPConnection(); 
  hc.setUserName(userName); 
  hc.setPassword(password); 
call.setSOAPTransport(hc);

3.13 Какой стиль WSDL мне следует использовать?

В документе WSDL содержится XML-код, который описывает Web-сервис. Привязка WSDL описывает то, как сервис связан с протоколом обмена сообщениями. Привязка WSDL SOAP может быть осуществлена либо при помощи вызова удаленных процедур (RPC), либо при помощи документной привязки. Привязка SOAP также может употребляться как в кодированном виде, так и в литеральном виде. Таким образом, у разработчика приложений Lotus Domino есть четыре типа/использования моделей на выбор:

  • вызов удаленных процедур/кодированный (RPC/encoded);
  • вызов удаленных процедур/литеральный (RPC/literal);
  • документальный/литеральный (Document/literal);
  • заключенный в оболочку (Wrapped).

Терминология «PRC против документального» может сбивать с толку, так как эти термины подразумевают, что тип RPC следует использовать для программируемых моделей RPC и что документальный тип нужно использовать для документальных программируемых моделей или для программируемых моделей обмена сообщениями. Тем не менее, в данном случае все эти заблуждения бессмысленны, так как тип не имеет ничего общего с программируемыми моделями. Типы только лишь диктуют то, как переводить привязку WSDL в сообщение SOAP. Подобно этому, типы кодированный и литеральный имеют значение только в привязке WSDL-к-SOAP.



 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 14.04.2007 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
IBM DOMINO COLLABORATION EXPRESS AUTHORIZED USER LICENSE + SW SUBSCRIPTION & SUPPORT 12 MONTHS
IBM DOMINO ENTERPRISE CLIENT ACCESS LICENSE AUTHORIZED USER LICENSE + SW SUBSCRIPTION & SUPPORT 12 MONTHS
IBM Domino Utility Server Processor Value Unit (PVU) License + SW Subscription & Support 12 Months
IBM Domino Enterprise Server Processor Value Unit (PVU) Annual SW Subscription & Support Renewal
IBM DOMINO ENTERPRISE CLIENT ACCESS LICENSE AUTHORIZED USER ANNUAL SW SUBSCRIPTION & SUPPORT RENEWAL
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
Мир OLAP и Business Intelligence: новости, статьи, обзоры
Новые программы для Windows
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100