Разработка веб-служб средствами Java. Ильдар ХабибуллинРазработкаWebслужбсредствами
Скачать 9.24 Mb.
|
, в котором вложен- ным элементом указывается адрес URI отправителя, элементом Обратный маршрут, если он нужен, указывается элементами Простейшее послание не содержит промежуточных адресов и адреса отпра- вителя. Оно выглядит примерно так: < ! — Содержимое послания... —> В этом примере показаны еще два обязательных элемента SOAP-послания, составленного по протоколу WS-Routing. Обязательный элемент 268 Разработка Web-служб средствами Java Обязательный элемент Заметьте, что адрес получателя в элементе Если надо указать промежуточные серверы, например, и то к посланию добавляется элемент и вложенные в элементы Глава 6. Детали создания Web Services Наконец, если нужно указать обратный путь, то добавляются элементы И В этом примере пустой элемент В стандартную поставку JAXM ВХОДИТ пакет содержащий всего два — SOAPRPMessageFactorylmpl И 270 Разработка Web-служб средствами Java — реализующих протокол WS-Routing и создающих SOAP-послания с профилем, названным Класс soAPRPMessageimpi расширяет класс soAPMessage, поэтому его эк- земпляр можно создать приведением экземпляра класса soAPMessage, полу- ченного методом createMessage О , К нужному типу: soaprpMsg = Затем, методами класса soAPRPMessageimpi и методами, унаследованными от класса soAPMessage, создаем SOAP-послание профиля При этом полезны следующие методы класса soAPRPMessageimpi: • public void — создает элемент мое — уникальный идентификатор послания; public void actor) — адресом actor; public void setFrom (Endpoint from) — создает элемент • public void (Endpoint to) — создает элемент • public void (String id) — ССЫЛКУ на послание с идентификатором id; public void actor, int position) — добавляет элемент public void actor) — добавляет мент При разборе послания полезны аналогичные методы: • public string () — возвращает содержимое эле- мента • public Endpoint — возвращает содержимое элемен- та • public Endpoint — возвращает содержимое элемента с адресом отправителя; • public Ebdpoint — возвращает содержимое элемента • public string getRelatesTo () — возвращает содержимое Глава 6. Детали создания Web Services 271 • public Vector — содержимое элемента • public Vector — содержимое элемента После создания и/или изменения послания следует обратиться к методу public void Пример использования этих методов приведен в листинге 6.4. Связь с поставщиком сообщений Связь с поставщиком сообщений устанавливается одним из двух способов. Первый способ — связаться с заранее определенным поставщиком, назы- ваемым поставщиком по умолчанию. Это осуществляется последовательным применением двух методов класса ProviderConnectionFactory: ProviderConnectionFactory pcf = ProviderConnection pc = Второй способ — найти поставщика сообщений через систему именования JNDI (Java Naming and Directory Interface) (см., например, [10]) его Context ctx = new ProviderConnectionFactory pcf = ProviderConnection pc = Конечно, поставщик сообщений должен быть уже зарегистрирован в систе- ме JNDI под определенным именем. В примере это имя "SomeProvider". И В ТОМ, И В Другом типа ProviderConnection. Интерфейс ProviderConnection описывает четыре метода работы с постав- щиком услуг. Установив связь с поставщиком, надо получить сведения о нем первым ме- тодом интерфейса ProviderConnection: public (); Этот метод заносит сведения о поставщике в объект типа ProviderMetaData. Объект содержит имя поставщика и номер версии по- ставщика, состоящий из двух чисел записанных через точку, вроде "1.2". Их можно получить методами Разработка Web-служб средствами Java public String public int public int Кроме этого, объект типа ProviderMetaData содержит список имен профи- лей, различаемых поставщиком. Этот список можно получить в виде масси- ва строк методом public String[] Получив сведения о поставщике и выбрав нужный профиль послания мож- но начать создание послания. Создание SOAP-послания и его отправка Создание SOAP-послания осуществляется методами класса MessageFactory из пакета SAAJ, так же, как это делалось в предыдущем разделе этой главы, но сначала надо получить экземпляр класса MessageFactory вторым мето- дом интерфейса ProviderConnection public MessageFactory profile); Затем, используя полученный экземпляр, создаем SOAP-послание с допол- нениями, если они нужны, и отправляем его получателю. Создание посла- ния сильно зависит от выбранного профиля. В листинге 6.4 создается SOAP-послание профиля SOAP-RP. Отправка SOAP-послания выполняется третьим методом интерфейса ProviderConnection: public void message); Как видите, метод send () не возвращает никакого значения и не требует, чтобы клиент, пославший сообщение, ждал ответа. Тем не менее, после ра- боты надо закрыть связь с поставщиком четвертым методом интерфейса ProviderConnection; public void close О; Листинг 6.4 показывает пример клиента системы JAXM, создающего SOAP- послание профиля с дополнением. Листинг 6.4. Создание и асинхронная отправка SOAP-послания import import import Глава 6. Детали создания Web Services 273 import public class public static void args){ String from ="http://some.com/soaprp/sender"; String to = "http://another.com/soaprp/receiver"; try{ ProviderConnectionFactory pcf = ProviderConnection pc = ProviderMetaData metaData = supportedProfiles = String profile = null; for (int i=0; i < i++){ if profile = break; MessageFactory = soaprpMsg = URL = new = 274 Разработка Web-служб средствами Java e){ Итак, мы научились писать клиентские приложения Web-служб на основе пакетов SAAJ и JAXM. Посмотрим, как можно создавать SOAP-серверы с помощью этих пакетов. В технологии Java SOAP-серверы реализуются классами специального вида, называемыми сервлетами. Сервлеты подробно описаны в книгах [10, 11]. Нам не обязательно знать все тонкости их создания и употребления, приве- дем здесь только необходимые сведения о них. Сервлеты (servlet) формально называется всякий класс, реализующий ин- терфейс из пакета Основу сервлета составляют ме- тод выполняющий начальные действия сервлета, метод destroy о, завершающий работу сервлета, и метод service о , в котором заключена вся работа сервлета. Основная особенность сервлета в том, что он работает не сам по себе, а в составе Web-сервера. Когда от клиента приходит запрос к сервлету, Web-сервер, а точнее один из его модулей, называемый Web-контейнером, загружает сервлет и обращается сначала к его методу i n i t (), а затем к методу service (). Метод i n i t () вы- полняется только один раз, при загрузке сервлета, при следующих запросах к сервлету сразу выполняется метод service о . Это очень похоже на работу апплета в браузере, откуда и произошло слово "сервлет". У метода service () два аргумента, его заголовок выглядит так: public void req, ServletResponse resp) throws ServletException, IOException; Глава 6. Детали создания Web Services 275 Первый аргумент req — это ссылка на объект типа создан- ный Web-контейнером при получении запроса от клиента, еще до обраще- ния к методу service Объект содержит в себе запрос клиента, различные параметры и атрибуты которого сервлет может получить несколькими мето- дами вида name), name). Для получения содержимого запроса интерфейс предоставляет два входных потока: байтовый поток класса и обычный символьный поток класса feredReader из пакета io. Второй аргумент resp — это ссылка на пустой объект типа servletResponse, тоже созданный Web-контейнером. Метод service о раз- бирает запрос, заключенный в объект req, методами интерфейса ServietRequest, обрабатывает его, и результат обработки заносит в объект resp методами интерфейса ServletResponse. Для этого интерфейс ServletResponse предоставляет байтовый выходной поток класса ServletOutputStream И СИМВОЛЬНЫЙ ВЫХОДНОЙ ПОТОК P r i n t W r i t e r . После заполнения объекта resp сервлет заканчивает работу. Web-контейнер анализирует содержимое объекта resp, формирует ответ, и пересылает его клиенту через Web-сервер, в котором работает Web-контейнер. В пакете есть абстрактный класс реализую- все методы интерфейса за исключением метода service о. Как правило, сервлеты, обрабатывающие произвольные Web-запросы, рас- ширяют GenericServiet, реализуя service () . В листинге 6.5 дан пример простого сервлета, отправляющего обратно со- держимое полученного запроса. ! Листинг 6.5. Простой сервлет import import j public class EchoServlet extends public void req, ServletResponse resp) throws ServletException, Servietinputstream sis = ServletOutputStream sos = int b = 0; while ((b = != -1) 276 Разработка Web-служб средствами Java Класс компилируется обычным образом и устанавливается в Web-контейнер. Установка (deployment) сервлета в контейнер — это проце- дура, в результате которой Web-контейнер "узнает" о существовании сервле- та, может найти его и загрузить. В процессе установки можно задать на- чальные параметры сервлета. При создании экземпляра сервлета эти на- чальные параметры заносятся в объект типа из которого их можно получить методами (string). Еще один метод ин- терфейса метод — позволяет ПОЛу- чить контекст, в котором выполняются все сервлеты Web-приложения, в виде объекта типа Процедура установки зависит от конкретного Web-контейнера. Обычно на- до поместить сервлет в какой-нибудь каталог Web-контейнера и записать путь к нему в определенный конфигурационный файл. Многие Web- контейнеры предлагают утилиты установки, например, у вхо- дящего в состав J2EE, есть утилита Интерфейс и класс ничего не знают о протоколе, по которому прислан запрос. Они не учитывают особенности протокола. Ввиду особой важности протокола HTTP для Web-приложений, для обра- ботки HTTP-запросов создан абстрактный класс — расшире- ние GenericServiet. В класс HttpServiet ванные методы обработки различных HTTP-методов передачи данных: protected void req, HttpservletResponse resp); protected void req, HttpservletResponse resp); protected void req, HttpservletResponse resp); protected void req, HttpservletResponse resp); protected void req, HttpservletResponse resp); protected void req, HttpservletResponse resp); protected void req, HttpservletResponse resp); Глава 6. Детали создания Web Services 277 Как видно из сигнатур этих методов, тип их аргументов тоже изменен. В HttpServletRequest, расширяющий интерфейс ServletRequest, введены методы getxxx() получения различных частей адреса URL, полей HTTP-заголовка и cookie. В интерфейс расширяю- щий интерфейс введены аналогичные методы формирующие заголовок HTTP-ответа и cookie. После загрузки сервлета класса Web-контейнер, как обычно, обращается последовательно к его методам и service о. Метод service о реализован в классе HttpServiet как диспетчер. Он только опре- деляет HTTP-метод передачи данных и обращается к соответствующему ме- тоду () обработки данного HTTP-метода. Разработчику не надо пере- определять метод service (), достаточно определить методы (), чаще всего определяются два метода: doGet () и doPost (). В листинге 6.6 приведен пример сервлета, принимающего HTTP-запрос вида GET HTTP/1.1 пришедший по методу GET или POST, и отправляющий его обратно в виде страницы HTML. Листинг 6.6. Сервлет, работающий по протоколу HTTP import .*; import import public class EchoHttpServlet extends public void req, resp) throws ServletException, resp); public void req, HttpservietResponse resp) throws ServletException, String name = 278 Разработка Web-служб средствами Java String age = = ; " + name + " "); " + age + " "); ; (); Класс HttpServiet С интерфейсами HttpServletRequest, HttpServietResponse и сопутствующими интерфейсами и классами, состав- ляет пакет j http. В технологии Java естественно оформлять Web-службы в виде сервлетов. Если Web-служба будет работать только по протоколу HTTP, то удобно соз- давать сервлеты, расширяющие класс HttpServiet. Если Web-служба долж- на работать по нескольким протоколам, то лучше расширить класс GenericServlet ИЛИ реализовать Servlet. И в том, и в другом случае сервлету приходится самому оформлять ответ в виде SOAP-послания, явно выписывая все его элементы XML. Даже теги странички HTML, как видно из предыдущего примера, надо записывать в методах print (). Для того чтобы облегчить создание сервлетов, принимающих и отправляю- щих SOAP-послания, в пакете messaging приведено одно рас- ширение класса HttpServiet. Это абстрактный класс JAXMServiet. Он предназначен для получения, обработки и отправки SOAP-посланий, оформленных средствами JAXM. Сервлеты класса JAXMServiet Класс JAXMServiet добавляет к классу HttpServiet три метода. Первый метод protected s t a t i c MimeHeaders req); Глава 6. Детали создания Web Services 279 заносит все поля HTTP-заголовка запроса req в объект класса Второй метод protected void headers, HttpServletResponse resp); формирует HTTP-заголовок ответа resp из заранее подготовленного объекта headers. Третий метод public void static factory); заносит В factory класса MessageFactory. В JAXMServlet Всегда есть объект класса MessageFactory. Это защищенное (protected) поле сервлета. Оно называется Объект, на который ссылается msgFactory, по умолчанию создается в мето- де i n i t () обычным для системы JAXM методом: m s g F a c t o r y = Кроме введения трех новых методов и переопределения метода i n i t (), соз- дающего объект msgFactory, класс JAXMServlet реализовал один из методов doxxx(), а именно метод Эта реализация вначале читает HTTP- заголовок и содержимое запроса: MimeHeaders headers InputStream is = ; и воссоздает исходное SOAP-послание в виде объекта класса soAPMessage, ИСПОЛЬзуя объект m s g F a c t o r y : SOAPMessage = i s ) ; Затем SOAP-послание msg передается на обработку методу onMessage(). Об этом методе поговорим чуть ниже. Если сервлет обслуживает асинхронный прием посланий, не требующих от- вета, то на этом работа метода doPost () и сервлета заканчивается, а в объ- ект resp заносится код ответа сервера "204 No Content". Если же сервлет работает по принципу Р2Р, осуществляя синхронную пере- дачу посланий, то в объект resp заносится результат работы метода onMessage (). Он-то и будет ответом SOAP-сервера на запрос клиента. На этом метод doPost о завершает свою работу. Таким образом, в сервлете класса JAXMServlet обработка SOAP-послания и формирование ответа на него выполняется не методом doPost а методом onMessage ( ) , ВХОДЯЩИМ В класс JAXMServlet. М е т о д () быть определен во всяком классе, расширяющем класс JAXMServlet, но не переопределяющем его метод Post о . 280 Разработка Web-служб средствами Java Кроме того, сервлет, расширяющий класс реализует собой ли- бо Web-службу, работающую с клиентом синхронно, либо Web-службу, ра- ботающую асинхронно. Реализация осуществляется так. Если Web-служба будет работать асинхронно, то сервлет должен реализовать интерфейс если СИНХроННО — интерфейс В каждом из этих интерфейсов описано всего по одному методу. Это и есть тот метод onMessage () , О МЫ говорили. В интерфейсе OnewayListener метод onMessage О не возвращает результат, его заголовок таков: public void В интерфейсе RegRespListener результатом метода будет новое SOAP- послание: public SOAPMessage msg); Если метод возвратил null, то ответ не будет передан клиенту. Итак, если мы хотим создать синхронную Web-службу, основанную на па- кете SAAJ, то расширяем класс JAXMServiet и реализуем интерфейс ReqRespListener, определяя метод onMessage о . Схема сервлета такова: import public class SyncSAAJServlet extends JAXMServiet implements public SOAPMessage msg){ // Разбираем послание msg, формируем ответное послание... Если же мы решили создать асинхронную Web-службу на основе пакета JAXM, то в сервлете, расширяющем класс JAXMServiet, следует реализовать интерфейс OnewayListener. Вот схема такого сервлета: import public class AsyncJAXMServlet extends JAXMServiet implements public void msg){ // Разбираем послание msg... Глава 6. Детали создания Web Services В листинге 6.7 показана реализация синхронной Web-службы, выводящей полученное послание в свой стандартный вывод и посылающей клиенту подтверждение в получении запроса. Реализация сделана в системе SAAJ сервлетом, который мы назвали AckJAXMServlet. Листинг Сервлет, отправляющий подтверждение | import import public class AckJAXMServlet extends JAXMServlet implements public SOAPMessage try{ полученного запроса:\п"); SOAPMessage reply = SOAPEnvelope env = return reply; e){ return null; Послания процедурного стиля Процедурный стиль SOAP-послания, предполагающий вызов удаленной процедуры, расположенной на SOAP-сервере, и получение ее результата, реализован в технологии Java пакетом JAX-RPC. Впрочем, средства пакета JAX-RPC позволяют реализовать и документный стиль SOAP-посланий. 282 Разработка Web-служб средствами Java Реализация пакета JAX-RPC основана на механизме обращения к методам удаленных объектов (Remote Method Invocation), с которым можно по- знакомиться, например, по книге [10]. Механизм RMI так глубоко спрятан в пакет JAX-RPC, что вы можете ничего про него и не знать. Он проявляет себя только в том, что удаленные объекты должны реализовать интерфейс, расширяющий интерфейс Remote из пакета Такой интерфейс на- зывается удаленным (remote) или распределенным (distributed) интерфейсом. Про интерфейс Remote тоже можно ничего не знать, потому что он пуст, он не содержит констант и заголовков методов. Пометка "extends Remote" в заголовке удаленного интерфейса означает только, что объекты этого типа будут распределенными объектами, доступными удаленным клиентам. Итак, при создании Web-службы средствами JAX-RPC сначала записывает- ся удаленный интерфейс, а Web-служба строится как реализация этого уда- ленного интерфейса. Суть механизма RMI заключается в том, что после того как клиент обра- тился к методу удаленного объекта, на его машину пересылается программ- ный код, называемый заглушкой (stub). Заглушка оформлена как класс Java, реализующий удаленный интерфейс, но реализация содержит не Web- услуги, а средства сетевого соединения, создания SOAP-посланий, включая их сериализацию, и средства пересылки SOAP-посланий. На сервере тоже создается дополнительный профаммный код, называемый серверной заглушкой или связкой (tie). Связка получает сообщение от клиент- ской заглушки, десериализует содержащееся в нем SOAP-послание, извле- кает из него аргументы Web-услуги и передает их Web-службе. Результат выполнения Web-услуги проходит обратный путь. Он сериализуется связкой и пересылается клиентской заглушке. Та десериализует полученное сообще- ние, извлекает из результат Web-услуги и передает клиенту как резуль- тат обращения к удаленному методу. Эта схема показана на рис. 6.2. Таким образом, с точки зрения клиента создается обычный локальный объ- ект Java, и обычным образом выполняются его методы, как будто они рабо- тают прямо на клиентской машине. Клиент Заглушка (Stub) JAX-RPC HTTP Web-служба Порт (Port) адресат Связка (Tie) -> JAX-RPC Рис. 6.2. Механизм JAX-RPC Глава 6. Детали создания Web Services 283 Создание Web-службы средствами JAX-RPC Из предыдущего описания видно, что для создания Web-службы надо, пре- жде всего, написать удаленный интерфейс, называемый в спецификации JAX-RPC "Service Endpoint Interface". Мы будем называть его адресатом или Web-службы. В WSDL-описании Web-службы адресату соответствует элемент . Поэтому вместе с его реализацией часто называется портом (port) Web-службы. Описанные в нем методы как раз и составляют Web-услуги создаваемой Web-службы. На этот интерфейс накладываются следующие условия: • он должен быть открытым (public); • он должен прямо или косвенно расширять интерфейс Remote; • он не должен содержать константы; • его методы должны выбрасывать исключение класса RemoteException; • другие исключения, выбрасываемые методами, могут быть только прове- ряемого (checked) типа; • аргументы методов и их возвращаемые значения могут быть только до- пустимых типов и не могут прямо или косвенно реализовывать интер- фейс Remote. SEI-интерфейс Web-службы может выглядеть примерно так, как показано в листинге 6.8. Листинг 6.8. Удаленный интерфейс Web-службы (порт) package import j public interface extends Book isbn) throws RemoteException; void setInfo(Book book) throws RemoteException; } К допустимым типам аргументов и возвращаемых значений относятся: • примитивные типы Java, кроме типа char, то есть типы boolean, byte, short, int, long, float, double; • соответствующие Boolean, Byte, Short, Integer, Long, Float, Double; 284 Разработка Web-служб средствами Java классы String, Date, • массивы, элементы которых относятся к перечисленным выше типам; • классы-коллекции типа Map, set; • классы Java, называемые в спецификации JAX-RPC "value types". Классы, названные "value types" — это обычные классы Java, удовлетворяю- щие трем требованиям. Они не реализуют прямо или косвенно интерфейс Remote, имеют открытый (public) конструктор по умолчанию, все их откры- тые (public) поля могут быть только допустимых для JAX-RPC типов. На- пример, класс Book, использованный в листинге 6.8, может выглядеть так: package bookinfo; public class Book{ private String isbn; private authors; private String t i t l e ; public public String return isbn; } public void isbn){ = isbn; } public getAuthors (){ return authors; } public void = authors; } public String getTitle()( return t i t l e ; } public void title){ = t i t l e ; } } Ограничения типов данных вызваны тем, что аргументы и возвращаемые значения сериализуются значениями типов языка XSD (см. главу Г). На- пример, ТИПЫ И I n t e g e r сериализуются ТИПОМ x s d : i n t , ТИП B i g l n t e g e r сериализуется типом xsd: i n t e g e r , типы Date и c a l e n d a r сериализуются ТИПОМ массивы ТИПОВ b y t e [ ] И Byte [) — ТИПОМ xsd:base64Binary. Типы классов-коллекций требуют наличия специальных классов, преобразующих их в структуры и массивы языка XSD. После создания надо его реализовать классом, который и будет представлять Web-службу. Этот класс в спецификации JAX-RPC на- зывается "Service Endpoint Class". Часто его называют служителем (servant). Глава 6. Детали создания Web Services 285 Очень часто имя класса-служителя образуется из имени добавлением окончания Класс-служитель должен удовлетворять следующим требованиям: • класс должен быть открытым (public), не абстрактным (abstract) и не окончательным (final); • у него должен быть открытый конструктор по умолчанию; методы, реализующие интерфейс, не должны быть окончательны- или статическими (static); • класс не должен реализовать метод {). В листинге 6.9 показано, как можно реализовать Web-службу средствами JAX-RPC. Листинг 6.9. Реализация Web-службы средствами JAX-RPC package bookinfo; import import j import import public class implements ServiceLifecycle{ private ArrayList books; private Connection con; public void ServletContext sc = String try{ con = e){} 286 Разработка Web-служб средствами Java public void con = null; } public try{ Statement st = ResultSet rs = FROM book" e){} public Book isbn){ Book t = null; for (int к = 0; к < О; к++){ t = if break; } return t; public void book){ } private void rs){ Глава 6. Детали создания Web Services 287 Заполнение списка книг books выборкой из базы } p r i v a t e void // Сохранение списка книг books в базе Обратите внимание на то, что класс-служитель — это не сервлет. Когда Web-служба будет устанавливаться в Web-контейнер, утилита установки ав- томатически создаст сервлет, который будет обращаться к методам класса- служителя. Обычно этот сервлет называется он входит в ка- ждую реализацию пакета JAX-RPC. Жизненный цикл Web-службы В листинге 6.9 реализуется еще один интерфейс описы- вающий жизненный цикл Web-службы. Описание производится двумя ме- тодами: public void context); public void выполняющимися автоматически под управлением ис- полняющей системы JAX-RPC по одному разу при создании экземпляра Web-службы и при завершении его работы соответственно. Исполняющая система создает и передает в метод i n i t () объект context, содержащий сведения о Web-контейнере, в котором работает Web-служба. Тип этого объекта указан просто как но им чаще всего бывает кон- текст сервлета типа или специально разработанный тип, ServletEndpointContext. Контекст Web-службы Интерфейс ServletEndpointContext описывает четыре метода, предостав- ляющие сведения об окружении, в котором работает Web-служба. • public HttpSession — передает сведения о НТТР- сеансе сервлета, под управлением которого работает Web-служба или null, если сервлет не участвует в сеансе; public () — передает сведения О полученном сообщении; 288 Разработка Web-служб средствами Java • public ServletContext — Web-приложения, в котором работает Web-служба; public Principal () — передает имя пользователя, обратившегося к Web-службе. Среди этих сведений особенно интересен интерфейс даже ОН, расширение Методы интерфейса MessageContext позволяют установить, получить, уда- лить свойства сообщения и узнать, есть ли свойство с заданным именем: public void name, Object value); public Iterator public Object name); public void name); public boolean name); Интерфейс SOAPMessageContext добавляет к этим методам еще три метода, которые позволяют получить и изменить присланное SOAP-послание: public SOAPMessage public void message); public [] Применяя эти методы в классах-обработчиках, можно сделать предвари- тельную обработку SOAP-послания и направить его другой Web-службе. Рассмотрим подробнее эти возможности. Предварительная обработка послания Средствами JAX-RPC можно сделать предварительную обработку SOAP- послания: раскодировать или закодировать сообщение, проверить подлин- ность сообщения, подтвердить права клиента. Очень часто предварительно обрабатываются блоки заголовка SOAP-послания, предназначенные для об- работки промежуточными серверами, но не прошедшие ее. Основу обработки задает интерфейс Handler. Он описывает методы, позво- ляющие обработать полученное SOAP-послание, отправляемое SOAP- послание и сообщение об ошибке: public boolean context); public boolean context); public boolean context); Хотя типом аргумента этих методов назван интерфейс MessageContext, на самом деле это тип SOAPMessageContext. Это дает возможность получить для обработки само SOAP-послание. Глава 6. Детали создания Web Services 289 Кроме того, в интерфейсе Handler есть метод public позволяющий получить блоки заголовка SOAP-послания. Еще два метода public void config); public void выполняются при создании объекта типа Handle и его удалении соответст- венно. В метод () передается ссылка на объект класса содержащий сведения, необходимые контейнеру для инициализации класса- обработчика, а также сведения о цепочке классов-обработчиков SOAP- послания. Дело в том, что для обработки SOAP-послания сразу создается целая цепоч- ка классов-обработчиков, даже если в нее входит только один обработчик. Цепочка обработчиков — это объект типа Интерфейс расширяет интерфейс List, значит, описывает упорядочен- ный список объектов типа Handler. К многочисленным методам интерфей- са List и его предка — интерфейса позволяющим работать со списком — добавлять, удалять и перебирать элементы списка, — интерфейс добавляет следующие методы: public boolean context); public boolean context); public boolean context); public void public void public public void Как видите, первые пять методов похожи на методы интерфейса Handler. Они включены в интерфейс HandierChain для того чтобы его объекты мож- но было включить в другую цепочку, получив тем самым вложенную цепоч- ку классов-обработчиков. Последние два метода позволяют цепочке играть роль "next" одного или нескольких промежуточных серверов (actors), обра- батывающих блоки заголовка SOAP-послания (см. главу 3). Методы () сделаны логическими именно потому, что они участ- вуют в цепочке — если метод handleRequest () вернул логическое значение true, то обработка пришедшего SOAP-послания передается следующему в цепочке методу handleRequest о, или адресату Web-службы, если обработ- чик был последним в цепочке. Если метод handleRequest () вернул значе- ние false, то следующие обработчики не вызываются, а послание передает- 748 290 Разработка Web-служб средствами Java ся методу () того же экземпляра класса-обработчика и дальше идет по цепочке методов handieResponse Если метод () класса SOAPFaultException, управление передается методу () того же экземпляра класса- обработчика. Впрочем, разработчик может изменить эту стандартную после- довательность действий по своему усмотрению. Для удобства реализации интерфейса Handler, в пакете JAX-RPC имеется его частичная реализация — абстрактный класс GenericHandler. Реализация тривиальна — все логические методы просто возвращают значение true, прочие методы пусты, и только метод getHeaders о оставлен абстрактным. Итак, класс-обработчик может выглядеть следующим образом: public class MyHandler extends public public boolean try{ SOAPHeader sh = // Обрабатываем блоки заголовка sh return true; ex){ } Цепочку классов-обработчиков SOAP-послания следует зарегистрировать у адресата или у клиента Web-службы. Для этого предназначен интерфейс описывающий два метода доступа к цепочке: public List portName); public void portName, List chain); Объект типа HandierRegistry можно получить методом public HandierRegistry ; интерфейса о котором речь пойдет ниже. Продолжим наш пример. Получаем цепочку и включаем в нее класс MyHandler: QName = new Глава 6. Детали создания Web Services 291 ServiceFactory sf = Service serv = reg = List chain = null, null)); Кроме регистрации классов-обработчиков в цепочке, их следует указать в конфигурационном файле. Как это сделать — рассказано ниже в этой главе. Компиляция файлов Web-службы Интерфейс и классы Book, а также другие нуж- ные классы компилируются обычным образом j avac ava Кроме интерфейса-порта, реализующего его класса и сопутствующих клас- сов, для работы Web-службы надо получить еще несколько классов, обеспе- чивающих реализацию механизма Это, в частности, клиентская за- глушка и серверная связка, классы, сериализующие и десериализующие сложные типы. Кроме того, надо сделать описание Web-службы на языке WSDL. Создать вручную эти классы очень сложно, они используют специфику ме- ханизма RMI, а это весьма запутанная система. Пакет Sun WSDP предлагает три утилиты для создания классов JAX-RPC. Это уже успевший устареть компилятор создающий и заглушки и связки, а также новые утили- ты: компилятор создающий серверные связки и описания WSDL, и компилятор создающий клиентские заглушки. Компилятор хгрсс работает из командной строки. Для создания серверных файлов он запускается примерно так: $ -server config.xml Для создания клиентских файлов указывается флаг -client. Если надо сра- зу создать все файлы, и серверные, и клиентские, то указывается флаг - both. Для работы компилятора хгрсс нужны уже откомпилированные SEI- интерфейс и его реализация классом-служителем, а также специальный конфигурационный XML-файл, описывающий Web-службу. Этот файл обычно называется config.xml. Его структура описана в документации, приложенной к компилятору хгрсс, и может в дальнейшем измениться вместе с ним. Разработка Web-служб средствами Java Компилятор тоже запускается из командной строки следующим образом: $ wsdeploy temp -о deployable.war Он получает информацию из архива deployable.war (имя файла может быть другим), в котором лежат откомпилированные классы, специальный конфи- гурационный файл с именем и конфигурационный DD-файл (Deployment Descriptor) Web-приложения [10]. Компилятор сразу же упаковывает все файлы созданной Web-службы в архив, в нашем примере это файл portable.war. Имя архива произвольно, обычно оно отражает на- звание Web-службы. Флаг -tmpdir указывает каталог для временных файлов, в примере это под- каталог temp текущего каталога. Если дополнительно указать флаг -keep, то в этом каталоге останутся исходные файлы всех классов. После этого остается установить Web-службу, то есть архивный файл (в примере — это файл portable.war), в Web-контейнер как обычное Web- приложение. Утилита установки, в частности, создает сервлет, который бу- дет представлять класс-служитель (tie) в Web-контейнере. Конфигурационный файл компилятора jaxrpc-ri.xml Конфигурационный файл jaxrpc-ri.xml компилятора wsdeploy — это XML- файл с корневым элементом Каждый элемент может появиться сколько угодно раз. У корневого элемента И идентификаторы СТраНСТВ ОПИСаНИЯ WSDL И ТИПОВ данных, атрибут urlPatternBase показывает начальный контекст Web-службы. Элемент • обязательный атрибут name определяет название Web-службы, оно будет служить именем файла WSDL с описанием Web-службы; необязательный атрибут определяет название Web-службы, используемое утилитами JAX-RPC и Web-контейнером в заголовках и пунктах меню; • необязательный атрибут description содержит произвольное описание Web-службы; • необязательный атрибут interface содержит имя Глава 6. Детали создания Web Services 293 необязательный атрибут implementation содержит имя класса- служителя; • необязательный атрибут model дает ссылку в виде строки URI на допол- нительное описание Web-службы. В элемент Элемент содержит путь к файлу с описанием WSDL. Он не содержит вложенных элементов, у него есть только два обязательных ат- рибута: • атрибут endpointName содержит имя файла с описанием WSDL; • атрибут определяет путь к нему. Вот схема файла version=" targetNamespaceBase=" typeNamespaceBase=" urlPatternBase=" xsd:string"> |