1 Лабораторная работа №4 Использование XML и среды Axis2 для создания клиентсервисного взаимодействия 1 Язык XML и его расширения 1.1 XML XML – eXtensible Markup Language – расширяемый (наращиваемый) язык разметки информации. Язык xml различает регистр букв. Служебная информация документа xml заключается в теги. Первый тег описывает версию xml: <?xml version="1.0" encoding="UTF-8"?>. Второй тег является корневым элементом иерархической структуры документа xml. Корневой элемент единственный, каждый элемент может содержать в себе произвольное количество элементов. Приведем синтаксис тегов и комментариев: <name attribute1=”value1” … attributeN=”valueN”> other information </name> <name attribute1=”value1” … attributeN=”valueN”/> <!-- no any other information --> XML имеет множество языков-расширений для описания одной и той же информации с разных точек зрения. Данная точка зрения (или, по-другому, пространство имен namespace) описывается очередным xml-документом. Создавая xml-документ, мы можем захотеть: 1) описать нашу информацию с помощью чужих тегов; 2) сделать свое пространство имен доступным а) другим пользователям; б) самим себе. В случае 1 внутри интересующего нас тега будем использовать атрибут xmlns (xml namespace). В случае 2а – targetNamespace. В случае 2б – оба этих атрибута, значения которых не важны, но должны совпадать. Синтаксис атрибутов: xmlns:AnyNSName=”useaddress1” <!--Any Name Space name--> xmlns=”useaddres2” targetNamespace=”myaddress” Пространство имен без имени будет являться пространством имен по умолчанию, и оно должно быть одно. Обращаться к элементам данного пространства имен можно так: <AnyNSName:ElemName> other information </ AnyNSName:ElemName> <ElemName> other information </ElemName> <!-- Default namespace --> Подключить пространство имен можно в теге, имя которого уже принадлежит этому пространству. <NSN:ElemN xmlns:NSN=”useaddress”> other information </NSN:ElemN> <!— Name Space Name => NSN --> Адрес useaddress во многом служит для идентификации пространства имен, сами их описания могут находиться внутри пользовательской машины, так что подключение к интернету может быть совсем необязательным. 1.2 SOAP Приведем пример использования SOAP (Simple Object Access Protocol) <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 2 soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <soap:Header> <t:Transaction xmlns:t="some-URI"> soap:mustUnderstand="1" 5 </t:Transaction> </soap:Header> <soap:Body> <m:GetLastTradePrice xmlns:m="some-URI"> <symbol>DEF</symbol> </m:GetLastTradePrice> </soap:Body> </soap:Envelope> Элемент Header содержит в себе служебную информацию для промежуточных узлов обработки. Характер информации описан в пространстве имен t, известном клиенту и серверу. Если mustUnderstand установлен в 1, тег внутри заголовка обязательно должен быть обработан, а в случае его нераспознавания клиенту возвращается ошибка. Нулевое mustUnderstand значение позволит проигнорировать незнакомый тег в заголовке конверта. Тело Body конверта содержит в себе полезную нагрузку. WSDL предоставит нам возможность выбора связывания с soap в стиле document либо RPC. Ответ soap в случае RPC (Remote Procedure Calling) должен содержать тег <m:GetLastTradePriceResponse xmlns:m="some-URI"> <price> 10.23 </price> </m:GetLastTradePriceResponse> где добавление Response к имени тега обязательно. 1.3 SCHEMA Этот вид xml-документа позволяет описать типы данных. Файлы схемы имеют расширение xsl. Пространство имен определено по адресу "http://www.w3.org/2001/XMLSchema". В указанном документе определены типы NSN:string, NSN:int, NSN:boolean, где NSN – имя пространства имен, ссылающееся на схему. В схеме можно определить простые типы: <element name="messageString" type="NSN:string"/> И составные: <element name="DoInOnlyRequest"> <complexType> <sequence> <element name="messageString" type="NSN:string"/> <element name="messageInteger" type="NSN:int"/> </sequence> </complexType> </element> В этой лабораторной работе требуется: 1) указать в теге использования схемы атрибут elementFormDefault="qualified"; 2) использовать только составные типы. 1.4 DTD DTD (Document Type Definition) – аналог схемы, но несколько устаревший. Самостоятельное изучение по желанию. 1.5 WSDL Пространство имен доступно по адресу http://schemas.xmlsoap.org/wsdl/, SOAP в данном случае будет представлять http://schemas.xmlsoap.org/wsdl/soap/. Корневой элемент 3 имеет название definitions. В него входят элементы: 1) types; 2) message; 3) portType; 4) binding; 5) service. Тег types представляет собой схему xsl. Тег message ссылается на тип из types, чтобы описать параметр посылаемого сообщения. Параметр описывается тегом part, рекомендуется его единственное число в сочетании с только составными типами. Тег portType включает в себя теги operation, каждый из которых имеет вход (тег input) и/или выход (тег output). Теги input и output ссылаются на имя сообщений message. Тег binding ссылается на тип порта, который он хочет увязать с протоколом http и конвертом soap. Первый тег обращается к пространству имен soap для этой цели. Последующие теги являются тегами operation, соответствующие этим же тегам в portType (должны совпадать имена). Для каждой операции указывается имя операции, которое будет использовано для передачи soap-сообщения, стиль кодирования (document или rpc), способ кодирования тела сообщений. Т.е. в стеке протоколов soap лежит ниже wsdl. Тег service объявляет порты, ссылающиеся на теги binding, элементами которых является адрес (объявлен в пространстве имен soap), по которому собственно и будет доступен сервис. Имя wsdl:service тега должно совпадать с именем сервиса в soap:addressтеге. Приведем пример. <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:this="http://apache.org/axis2/packet" targetNamespace="http://apache.org/axis2/packet" > <wsdl:types> <schema elementFormDefault="qualified" targetNamespace="http://apache.org/axis2/packet" xmlns="http://www.w3.org/2001/XMLSchema"> <element name="TRequest"> <complexType> <sequence> <element name="Param" type="string"/> </sequence> </complexType> </element> <element name="TResponse"> <complexType> <sequence> <element name="Value" type="string"/> </sequence> </complexType> </element> </schema> </wsdl:types> <wsdl:message name="MRequest"> 4 <wsdl:part name="request" element="this:TRequest" /> </wsdl:message> <wsdl:message name="MResponse"> <wsdl:part name="response" element="this:TResponse"/> </wsdl:message> <wsdl:portType name="PortTypeName"> <wsdl:operation name="wsdlOpN" parameterOrder="input"> <wsdl:input message="this:MRequest" /> <wsdl:output message="this:MResponse" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="BindingName" type="this:PortTypeName"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="wsdlOpN"> <soap:operation soapAction="soapOpN" style="document" /> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="S"> <wsdl:port name="PortName" binding="this:BindingName"> <soap:address location="http://localhost:8080/axis2/services/S" /> </wsdl:port> </wsdl:service> </wsdl:definitions> 2 Среда разработки Axis2 2.1 Структура дистрибутива Axis2 Рассмотрим следующие папки, входящие в дистрибутив Axis2: 1) bin; 2) conf; 3) lib; 4) repository; 5)samples; 6) webapp. В bin входят утилиты (для windows *.bat, для unix - *.sh): axis2, axis2server, wsdl2java, java2wsdl. По крайней мере в двух последних утилитах цифра 2 означает предлог to и, следовательно. конвертирование от левой части названия к правой. Утилита axis2 запускает клиента, axis2server – сервер. Для выполнения этих команд системе требуется знать корневой каталог виртуальной машины Java (папка jdk ) и дистрибутива Axis2. Для этого выполняем команды (удобно прописать их в начале каждого батника): set AXIS2_HOME = path2axis2 set JAVA_HOME = path2jdk 5 Папка conf содержит axis2.xml – global deployment descriptor (перевести самостоятельно) Папка lib содержит jar-архивы. Клиента можно запустить утилитами java и axis2. В первом случае все jar-архивы надо подключить вручную, axis2 делает это автоматически. Для ручного подключения надо помнить о следующих возможностях: 1) команда dir возвращает список файлов в текущей директории; 2) ключ /b оставит от информации о файлах только имена; 3) шаблон *.jar оставит только jar-файлы; 4) знак > направит результаты в файл; 5) существует возможность автоматической замены .jar на .jar;smth\, где smth – путь до директории lib; 6) существует возможность вручную стереть ;smth\ после последнего имени jar-файла и добавить smth\ перед первым; 7) подключаются jarфайлы командой set CLASSPATH=.;path1\jar1.jar ; … ; path2\jar2.jar. Папка repository содержит в себе подкаталог services, в котором имеются zip-архивы с расширением aar. Чтобы сервер после запуска (утилита axis2server) предоставил данный сервис, нужно получить его aar-файл, поместить его в папку repository/services, а в файле repository/services/services.list добавить название этого aar-файла. Папка samples содержит в себе примеры. Папка webapp содержит в себе build.xml файл (и другую информацию), который описывает работу сервера axis2. Команда ant create.war ищет в текущей директории (по умолчанию) build файл и на основании его строит war-файл (WebARchive). WAR-файл можно поместить в папку webapp какой-либо другой среды (например, tomcat), так что мы получим ту же функциональность (требуется только следовать указаниям этой среды). При создании war-файла используется содержимое папок repository и conf. 2.2 Утилита wsdl2java 2.2.1 Опции Axis2 предоставляет следующие виды сервисов: in-out (запрос-ответ) и in-only (только запрос). В файле wsdl это отразится в теге <operation>: для in-out будут предусмотрены input и output элементы, для in-only – только input-элемент. После отправки сообщения до получения ответа приложение может выполнять какую-либо работу либо может быть блокировано (обеспечена синхронизация). Параметром утилиты wsdl2java задается wsdl-файл. Результатом являются сгенерированные описания поведения сервера или клиента на языке java. Предусмотрены следующие опции: -uri – wsdl-файл ; -p – пакет, в который будут помещены сгенерированные классы; -d – метод генерации, бывают: Axis2 Data Binding framework (adb), XMLBeans и JiBX databinding, указать adb, остальные – самостоятельное изучение по желанию; -s – синхронизация (synchronous); -wv – версия wsdl, указать 1.4.1 (wsdl version); -ss – генерируется серверная сторона (server side); -sd – генерируется services.xml (service descriptor), игнорируется при создании клиента; -o – папка, в которую будет помещено все сгенерированное. 2.2.2 Сервер Запускаем wsdl2java c ключом –ss. Создается папка, указанная ключом –о. В нее помещается папка src. В src помещаются пакеты, указанные: 1) ключом –р, 2) в targetNamespace тега types wsdl-файла (который задается ключом -uri). В первом пакете находятся описания классов SMessageReceiverInOnly.java, SMessageReceiverInOut.java и SSkeleton.java, где первая буква S – имя сервиса в файле 6 wsdl. Первые два файла генерируются в случае наличия соответственно in-only или in-out сервисов. Во втором пакете находятся классы с именами тегов element тега types wsdl-файла (составных элементов). Имена полей класса соответствуют при этом именам простых элементов, входящие в составные. Имеется также ExtensionMapper.java (перевести самостоятельно). Рекомендуется давать одно название этим пакетам, иначе рекомендуется самостоятельное изучение утилиты ant. Большое количество вложенных папок нужно для поддержания ясной структуры системы, созданной разработчиками и в принципе необязательно. Пример. Для примера из п. 1.5 выполним следующую команду: set JAVA_HOME=c:\java\jdk1.6.0\ set AXIS2_HOME=c:\axis2-1.4.1\ c:\axis2-1.4.1\bin\wsdl2java -uri wsdlcode.wsdl -d adb -p org.apache.axis2.packet -s -ss -sd -wv 1.4.1 -o server Получим папку server с содержимым: 1) папка resources, содержит S.wsdl, равный wsdlcode.wsdl, и services.xml; 2) папка src, содержит вложенные папки org/apache/axis2/packet с содержимым: ExtensionMapper.java, SMessageReceiverInOut.java, SSkeleton.java, TRequest.java, TResponse.java; 3) build.xml (нужен для утилиты ant). В файле *Skeleton находим метод с названием тега operation wsdl-файла. Тип входного параметра и возвращаемого значения очевидны. Нам потребуются методы get* и set*, где вместо * нужно подставить соответствующие имена простых элементов, входящие в составные элементы. Для SSkeleton получим примерно следующее: public org.apache.axis2.packet.TResponse wsdlOpN ( org.apache.axis2.packet.TRequest tRequest ) { //TODO : fill this with the necessary business logic //throw new java.lang.UnsupportedOperationException("Please //implement " + this.getClass().getName() + "#wsdlOpN"); System.out.println("It seems, somebody wants me"); String s=tRequest.getParam(); org.apache.axis2.packet.TResponse tResponse=new org.apache.axis2.packet.TResponse(); tResponse.setValue(s); return tResponse; } Рекомендация: не забыть закомментировать исключение. 2.2.3 Клиент Команда wsdl2java генерирует папку src с пакетом –р и build.xml. В пакет –р входит файл *Stub.java. В нем в качестве внутренних классов объявлены все необходимые типы. Для реализации функциональности клиента создается свой файл c любым именем. Для SStub справедливо, например, создать следующий Client.java файл package org.apache.axis2.packet; import org.apache.axis2.packet.SStub.TRequest; import org.apache.axis2.packet.SStub.TResponse; public class Client { public static void main(java.lang.String args[]){ if (args.length==0) {System.out.println("input an expression"); return;}; 7 String expr=args[0]; for (int i=1;i<args.length;i++) expr+=" "+args[i]; System.out.println("Ok. You\'ve inputted the next: "+expr+"."); try{ SStub stub = new SStub("http://localhost:8080/axis2/services/S"); TRequest request = new TRequest(); request.setParam(expr); TResponse response=stub.wsdlOpN(request); String answer=response.getValue(); System.out.println("server\'s answer: "+answer); } catch(Exception e){ e.printStackTrace();} } } 2.3 Утилита Ant В директории, где находится build.xml файл запускаем команду ant c аргументом: для сервера - jar.server, для клиента - jar.client. Например: set JAVA_HOME=c:\java\jdk1.6.0 set AXIS2_HOME=c:\axis2-1.4.1 c:\apache-ant-1.7.1\bin\ant jar.client В результате появляется каталог build с подкаталогом lib. В случае сервера в нем мы найдем aar-файл (который поместим в папку repository/services/), в случае клиента – jarархив (который подключим в CLASSPATH). 3 Задание Скачать Axis2. Скачать Ant. Написать wsdl описание для своего варианта. Сгенерировать сервер утилитой wsdl2java. Реализовать функциональность сервера. Построить сервер утилитой ant. Сгенерировать клиент утилитой wsdl2java. Реализовать функциональность клиента. Построить клиента утилитой ant. Запустить сервер. Запустить клиента. Остановить сервер. Варианты 4 Литература 1 http://w3schools.com/ 2 http://ws.apache.org/axis2/1.4.1/userguide