Web-сервисы Java: Знакомимся с CXF

Еще одна инфраструктура Web-сервисов от Apache Software Foundation

Стек Web-сервисов CXF от Apache поддерживает связывание с данными JAXB 2.x (наряду с некоторыми альтернативными вариантами связывания) а также конфигурирование сервисов JAX-WS 2.x. Как и инфраструктура Metro JAXB/JAX-WS, обсуждавшаяся в предыдущих статьях, CXF использует XML-файлы для расширения конфигурационной информации JAX-WS. В этой статье цикла «Web-сервисы Java» Деннис Сосноски рассмотрит основы применения инфраструктурs CXF для разработки клиентской и серверной части Web-сервиса.

Денис Сосноски, консультант, Sosnoski Software Solutions, Inc.

Денис Сосноски (Dennis Sosnoski) - основатель и ведущий специалист консалтинговой компании по технологиям Java - Sosnoski Software Solutions, Inc., специализирующейся в обучении и консультировании по проблемам XML и Web-сервисов. Он имеет более чем 30-летний опыт работы в профессиональном проектировании ПО, специализируясь на серверных XML и Java-технологиях. Денис является основным разработчиком интегрированной системы с открытым программным кодом JiBX XML Data Binding, построенной на базе технологии классов Java и связанной системы Web-сервисов JibxSoap, также как и системы Web-сервисов Apache Axis2. Он также был одним их экспертов при разработке спецификаций JAX-WS 2.0.



19.12.2011

CXF - это еще один стек Web-сервисов от Apache Software Foundation – той же группы, которая разработала Axis2. Хотя эти стеки разработаны в одной организации, Axis 2 и CXF используют очень разные подходы к конфигурированию и исполнению Web-сервисов. В этой статье мы узнаем об основах использования JAXB 2.x и JAX-WS 2.x для работы с Web-сервисами с помощью CXF, а также сравним CXF с другими стеками на основе JAXB/JAX-WS: Axis2 и Metro, которые мы обсуждали в предыдущих статьях.

Основы CXF

Пользовательский интерфейс CXF имеет много общего с интерфейсами стеков Axis2 и Metro. Все три стека позволяют создать Web-сервис на основе существующего кода Java™ или же сгенерировать код Java на основе WSDL-описания для использования или реализации сервиса. Как и другие стеки, CXF моделирует операции с сервисом в виде вызовов методов, а порты сервиса (portType) - в виде интерфейсов.

Об этом цикле статей

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

Аналогично Axis2, но в противоположность Metro, CXF позволяет выбирать между различными технологиями связывания с данными. CXF поддерживает связывание с данными JAXB 2.x наравне с Metro и несколько лучше, чем Axis2, потому что он позволяет настраивать JAXB при генерации кода из WSDL-описания сервиса (Axis2 этого не позволяет). CXF также позволяет использовать другие методы связывания с данными, хотя их поддержка реализована не так хорошо, как в Axis2. Например, генерировать код из WSDL-файла в CXF можно только при использовании связывания с данными JAXB или XMLBeans.

Предпочтительным методом конфигурирования сервиса (который в терминологии CXF называется frontend) в CXF являются аннотации JAX-WS 2.x, дополняемые конфигурационными XML-файлами. Поддержка аннотаций JAX-WS в CXF находится на одном уровне с Metro, что делает эту инфраструктуру намного предпочтительнее для работы с JAX-WS, чем Axis2 (поддержка JAX-WS в котором имеет несколько серьезных ограничений, которые обсуждались в статье "JAXB и JAX-WS в Axis2"). Как и другие реализации JAX-WS, CXF требует наличия WSDL-описания на стороне клиента во время выполнения.

Как и в других стеках, в CXF обработка запросов и ответов осуществляется набором конфигурируемых компонентов. В CXF эти компоненты называются перехватчиками (intercepters), а не обработчиками (handlers), но, несмотря на разные названия, эти термины обозначают одни и те же компоненты. Как и Metro, CXF в базовой загрузке поддерживает WS-Security и другие дополнительные технологии. В отличие от Metro, JAR-архивы CXF являются модульными. В зависимости от используемых технологий вы можете выбрать и включить в свое приложение лишь нужные вам файлы (в директории CXF в файле /lib/WHICH_JARS описывается, какие JAR-файлы нужны при различных типовых вариантах использования). Недостатком такой модульности является то, что в итоге, возможно, придется иметь дело с длинным списком JAR-файлов, нужных вашему приложению, а достоинством - то, что она позволяет сократить размер разворачиваемого приложения.

Как и Metro, CXF обычно требует собрать для Web-сервиса один WAR-файл вместо развертывания потенциально нескольких сервисов внутри одного сервера (подход, применяемый в Axis2). CXF также предоставляет встроенный HTTP-сервер Jetty, пригодный для использования в рабочей среде. Он является более гибкой и мощной альтернативой простым серверам HTTP, интегрированным в Axis2 и Metro.


Пример приложения

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

  • getBook возвращает подробную информацию по книге. Книга идентифицируется по международному стандартному номеру ISBN (International Standard Book Number).
  • getBooksByType возвращает подробную информацию обо всех книгах определенного типа.
  • getTypes возвращает имеющиеся типы книг.
  • addBook добавляет в библиотеку новую книгу.

В статье "JAXB и JAX-WS в Axis2" мы видели, как это приложение работало в Axis2, затем в статье "Introducing Metro", мы рассмотрели его работу в Metro. Большая часть рассуждений, приведенных в предыдущих статьях, также применима и для CXF. Описание WSDL выглядит точно так же, за исключением имени сервиса и адреса конечной точки. Сгенерированная модель данных JAXB тоже такая же. Идентичны даже сгенерированные классы сервиса, за исключением пакета Java и имени сервиса, используемого в аннотациях JAX-WS.

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

Клиентский код для нашего приложения на CXF идентичен использованию JAX-WS в Axis2 или Metro. Шаги по сборке клиента также очень похожи: используйте входящую в CXF утилиту wsdl2java вместо разработанной для JAX-WS программы wsimport. За подробной информацией о работе с клиентским кодом обращайтесь к статье "JAXB и JAX-WS в Axis2".

Хотя клиентский код одинаков, в поведении клиента CXF имеется существенное отличие. По умолчанию CXF выводит в консоль слишком большое количество информации. CXF использует пакет Java Logging, поэтому, чтобы избавиться от этого, необходимо указать приложению на файл настроек журналирования, сконфигурированный для вывода информации только на уровнях WARNING или SEVERE. В Ant в файле build.xml нашего приложения адрес этого конфигурационного файла указывается с помощью следующего параметра JVM: <jvmarg value="-Djava.util.logging.config.file=${build-dir}/logging.properties"/>.

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

Серверный код нашего приложения на CXF также идентичен использованию JAX-WS в Axis2 или Metro. Процесс сборки также очень похож на Metro. В Axis2, мы подготавливали сервис к развертыванию, создавая JAR-файл с классами сервиса и модели данных, а затем разворачивали сервис, помещая этот JAR-файл в директорию WEB-INF/servicejars сервера Axis2. В Metro и CXF вместо этого нужно создать WAR-файл, содержащий классы сервиса и модели данных, библиотечные JAR-файлы Metro или CXF и пару конфигурационных файлов (один из которых называется по разному в этих двух стеках). В файле WEB-INF/web.xml конфигурируется непосредственно обработка запросов сервлетом. В листинге 1 показана версия этого файла, используемая в нашем приложении:

Листинг 1. Файл web.xml в примере приложения
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee">
  <display-name>CXFLibrary</display-name>
  <description>CXF Library Service</description>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
      classpath:META-INF/cxf/cxf.xml
      classpath:META-INF/cxf/cxf-extension-soap.xml
      classpath:META-INF/cxf/cxf-servlet.xml
     </param-value>
  </context-param>
  <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

Приведенный в листинге 1 файл WEB-INF/web.xml является всего лишь стандартным конфигурационным файлом сервлета, сообщающим серверу Web-приложений (например Tomcat), как взаимодействовать с сервлетом. Данный файл похож на файл, использованный в примере для Metro, хотя для CXF атрибут <servlet-class> является частью кода CXF, а <listener-class> указывает на класс инфраструктуры Spring (см. Ресурсы). Как и в примере для Metro, сервлет сконфигурирован так, чтобы обрабатывать все запросы, поступающие к данному Web-приложению (это делается в атрибуте <url-pattern>/</url-pattern>).

Отдельный файл - WEB-INF/cxf-servlet.xml - используется для настройки в CXF маршрутизации получаемых сервлетом запросов к коду сервиса и задания адреса, по которому можно будет обнаружить WSDL - описание сервиса. Этот файл показан в листинге 2:

Листинг 2. Файл cxf-servlet.xml в примере приложения
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:jaxws="http://cxf.apache.org/jaxws"
      xmlns:soap="http://cxf.apache.org/bindings/soap"
      xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
         http://cxf.apache.org/jaxws
         http://cxf.apache.org/schemas/jaxws.xsd">

    <jaxws:endpoint
        id="Processor"
        implementor="com.sosnoski.ws.library.cxf.CXFLibraryImpl"
        wsdlLocation="WEB-INF/wsdl/library.wsdl"
        address="/">
    </jaxws:endpoint>
</beans>

В файле WEB-INF/cxf-servlet.xml из листинга 2 определяется одна конечная точка сервиса с классом реализации, шаблоном запросов и местоположением документа WSDL. Адрес документа WSDL является единственной необязательной частью определения конечной точки. Если в файле cxf-servlet.xml не указать для конечной точки сервиса адрес документа WSDL, то CXF автоматически сгенерирует его во время выполнения на основе аннотаций JAX-WS.

Сборка и запуск кода

Проблемы сборки

Начиная с Java SE 6, реализации JAXB 2.x и JAX-WS 2.x (за исключением расширений) стали частью стандартных библиотек Java Runtime Environment (JRE). Это было сделано для поощрения использования этих технологий. Однако у этого благого намерения обнаружилась неприятная оборотная сторона: теперь при необходимости использовать свежие версии данных библиотек необходимо изменять уже установленную JRE.

Файл build.xml, используемый в нашем примере приложения, копирует необходимые CXF JAR-файлы непосредственно в WAR-файл сервиса. В их число входят JAR-файлы JAXB и JAX-WS для сборки на Java SE 5; но когда вы делаете сборку на Java SE 6, процедура сборки будет использовать версии JAXB и JAX-WS из установки JVM. Если конфликты загрузки файлов вызывают проблемы в коде JAXB или JAX-WS при использовании Java SE 6 или более новой версии, проверьте, есть ли к вашему дистрибутиву CXF какие-нибудь замечания о совместимости с различными версиями JVM.

Перед началом работы с примером приложения, вам нужно загрузить и установить себе на систему текущую версию CXF (см. Ресурсы). Код приложения тестировался с версией 2.2.5. Также нужно отредактировать файл build.properties, находящийся в корневом каталоге. Найдите в нем атрибут cxf-home и задайте ему значение пути, по которому установлен CXF. Если вы будете тестировать приложение с сервером, работающем на другой машине, или порту, отличном от стандартного, вам следует изменить атрибуты host-name и host-port.

Чтобы собрать приложение с помощью файла build.xml для Ant, откройте консоль в корневой директории кода приложения и выполните команду ant. Эта команда сначала запускает программу wsdl2java (включенную в дистрибутив CXF), затем скомпилирует код клиента и сервера, и, наконец, упакует код сервера в WAR-архив. Затем можно развернуть сгенерированный файл cxf-library.war на тестовом сервере, и, набрав в консоли ant run, запустить клиент приложения. Клиент выполняет серию запросов к серверу, печатая краткую информацию о результате каждого запроса. Как уже упоминалось в разделе Использование на клиентской стороне, при сборке мы сконфигурировали журналирование CXF так, чтобы избежать вывода детальной информации при запуске клиента.


Spring в CXF

Обратите внимание, что в конфигурационном файле cxf-servlet.xml, указанном в листинге 2, фактически конфигурируется bean-компонент Spring Framework. Как вы, возможно, знаете, Spring - это инфраструктура с открытым исходным кодом для разработки приложений. Она включает в себя множество компонентов и библиотек, которые можно использовать в своем приложении. Изначально в основе Spring лежал контейнер Inversion of Control (IoC). Он позволяет связывать и конфигурировать JavaBean - компоненты, используя механизм отражения Java для доступа к свойствам bean-объектов во время выполнения.

Контейнер Spring IoC, как правило, использует для получения информации о зависимостях XML-файлы. Приведенный в листинге 2 файл cxf-servlet.xml является примером подобного конфигурационного файла Spring. Элемент <beans> является всего лишь оболочкой конфигурации конкретного bean-элемента. Элемент <jaxws:endpoint> является таким bean-элементом, который CXF ассоциирует с определенным типом объектов (экземпляром класса org.apache.cxf.jaxws.EndpointImpl).

В файле cxf-servlet.xml можно указать множество других параметров, не используемых в этом простом примере, в том числе конфигурацию потока сообщений сервиса. С детальной информацией о конфигурации JAX-WS можно ознакомиться в документации CXF (в разделе Frontends/JAX-WS).

За исключением аннотаций JAX-WS, Spring используется для всей конфигурации стека CXF, в том числе для организации работы внутренних сообщений CXF. В большинстве случаев все детали настройки обрабатываются автоматически, с помощью конфигурационных XML-файлов, включенных непосредственно в CXF (в параметре contextConfigLocation в файле web.xml из листинга 1, можно увидеть, как именно эти файлы указываются). Однако типичную конфигурацию можно переопределить или расширить, используя свои собственные конфигурационные файлы. Мы не будем рассказывать об этом в данном цикле статей, за подробной информацией по этой теме обращайтесь к документации CXF.


Продолжим знакомство с CXF

В данной статье мы познакомились с основами работы со стеком Web-сервисов CXF, а именно с использованием связывания с данными JAXB 2.x и основанной на аннотациях конфигурации JAX-WS 2.x. Код для JAXB/JAX-WS, использованный ранее в статьях, посвященных Axis2 и Metro, также работает и в CXF. Мы сделали лишь несколько незначительных изменений в настройках сборки и использовали другой файл развертывания и конфигурации. Такая совместимость является главным преимуществом использования JAXB и JAX-WS, так как она облегчает переключение между стеками.

В CXF имеется множество возможностей, не раскрытых в этом простом примере, и в следующих статьях мы расскажем о некоторых из них. В следующей статье мы рассмотрим использование WS-Security, и сравним реализацию этой технологии в CXF с реализациями в Axis2 и Metro.


Загрузка

ОписаниеИмяРазмер
Исходный код примера для этой статьиj-jws12.zip16КБ

Ресурсы

Научиться

Получить продукты и технологии

  • Загрузите CXF.

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java, SOA и web-сервисы, Open source
ArticleID=781693
ArticleTitle=Web-сервисы Java: Знакомимся с CXF
publish-date=12192011