Как построить клиент веб-службы с планом
Мы создали WAR с одним сервлетом и одним JPS и преобразовали его в пакет, используя плагин maven bundle. Сервлет и jsp работают нормально в Apache Karaf с pax-web. Теперь я хотел бы использовать клиент веб-службы в этом сервлете. Как я могу этого достичь?
До сих пор мы использовали плагин cxf-codegen maven для создания всех необходимых классов для сборки клиента. У нас есть все зависимости: cxf-rt-transports-http, cxf-rt-ws-addr, cxf-rt-ws-policy, cxf-rt-frontend-jaxrs,cxf-rt-ws-security и cxf-rt- Транспорт-http-причал объявлен в Maven. Кроме того, у меня есть следующая запись в blueprint.xml:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd">
<bean id="myServlet" class="com.production.dashboard.DataCombination">
<property name="dataMergingService" ref="dataMergingService"/>
</bean>
<service ref="myServlet" interface="javax.servlet.http.HttpServlet">
<service-properties>
<entry key="alias" value="/hello" />
</service-properties>
</service>
<jaxws:client id="dataMergingService"
serviceClass="com.production.engine.datacombination.OrderDataMergingService"
address="http://localhost:8181/engine/datacombination?wsdl" />
Когда я использую этот подход, инъекция завершается неудачно, потому что клиент всегда нулевой.
Может ли кто-нибудь объяснить мне, как клиент веб-службы должен использоваться в OSGi, проекте и в связке с военным комплектом?
Спасибо заранее.
Приветствия Хильдериха
2 ответа
Приятно слышать от вас. Тем временем я достиг лучшего понимания Java-приложений, работающих в контейнерах OSGi.
Прежде всего, мое приложение - это обычное веб-приложение на Java, т.е. WAR. С дополнительными метаданными OSGi Manifest (Web-ContextPath, Webapp-Context) этот WAR был включен в пакет веб-приложений (WAB). Кроме того, как вы упомянули выше, blueprint.xml не был распознан контейнером OSGi Apache Karaf, потому что не было метаданных Manifest (Bundle-Blueprint), которые пытается обнаружить Blueprint Extender.
Плагин maven bundle (т. Е. Инструмент bnd) создает WAB для каждой сборки.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<inherited>true</inherited>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<supportedProjectTypes>
<supportedProjectType>jar</supportedProjectType>
<supportedProjectType>bundle</supportedProjectType>
<supportedProjectType>war</supportedProjectType>
</supportedProjectTypes>
<instructions>
<Bundle-SymbolicName>${web.contextPath}</Bundle-SymbolicName>
<Bundle-ClassPath>
.,
WEB-INF/classes,
WEB-INF/lib/jstl-1-2.jar,
WEB-INF/lib/ops4j-base-io-1.4.0.jar,
WEB-INF/lib/ops4j-base-lang-1.4.0.jar,
WEB-INF/lib/ops4j-base-monitors-1.4.0.jar,
WEB-INF/lib/ops4j-base-store-1.4.0.jar,
WEB-INF/lib/ops4j-base-util-property-1.4.0.jar,
WEB-INF/lib/org.ops4j.pax.tipi.hamcrest.core-1.3.0.1.jar,
WEB-INF/lib/standard-1.1.2.jar
</Bundle-ClassPath>
<Bundle-Blueprint>WEB-INF/classes/OSGI-INF/blueprint/*.xml</Bundle-Blueprint>
<Web-ContextPath>${web.contextPath}</Web-ContextPath>
<Webapp-Context>${web.contextPath}</Webapp-Context>
<Export-Package>
!org.production.engine.datacombination
</Export-Package>
<Import-Package>
javax.servlet,
javax.servlet.http,
javax.servlet.*,
javax.servlet.jsp.*,
javax.servlet.jsp.jstl.*,
!junit.framework,
!org.junit,
!sun.misc,
!org.ops4j.pax.swissbox.*,
*
</Import-Package>
<DynamicImport-Package>
javax.*,
org.xml.sax,
org.xml.sax.*,
org.w3c.*
</DynamicImport-Package>
</instructions>
</configuration>
</execution>
</executions>
</plugin>
Однако для запуска веб-приложения в Apache Karaf необходимо установить функцию war:
features:install war
Кроме того, jre 1.6 пришлось экспортировать дополнительные пакеты (выдержка из jre.properties):
jre-1.6= \
...
com.sun.org.apache.xalan.internal.res, \
com.sun.org.apache.xml.internal.utils, \
com.sun.org.apache.xpath.internal, \
com.sun.org.apache.xpath.internal.jaxp, \
com.sun.org.apache.xpath.internal.objects
При всем том, что Servlet Container (Jetty) работал и страницы JSP отображались правильно.
Теперь я объясню, как использовать клиент веб-службы в сервлете. С файлом WSDL, расположенным в каталоге ресурсов, я создаю все необходимые классы для построения клиента веб-службы. Чтобы сделать это легко, Maven cxf-codegen-plugin создает следующие классы:
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
<encoding>UTF-8</encoding>
<wsdlOptions>
<wsdlOption>
<wsdl>src/main/resources/datacombination_1.wsdl</wsdl>
<wsdlLocation>classpath:datacombination_1.wsdl</wsdlLocation>
<extraargs>
<extraarg>-b</extraarg>
<extraarg>${basedir}/src/main/resources/jaxb-binding-date.xml</extraarg>
<extraarg>-compile</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
Теперь я могу связать сгенерированные классы веб-сервиса с реальным веб-сервисом внутри blueprint.xml и опубликовать его как сервис OSGi:
<jaxws:client id="dms"
serviceClass="org.production.engine.datacombination.OrderDataMerging"
address="/engine/datacombination"
wsdlLocation="classpath:/datacombination_1.wsdl"
serviceName="ns1:OrderDataMergingService"
endpointName="ns1:OrderDataMergingPort" />
<service ref="dms" interface="org.production.engine.datacombination.OrderDataMerging" />
Внутри класса Servlet я смог создать экземпляр сгенерированного класса Service, и веб-служба была вызвана на удаленной машине:
OrderDataMergingService dataMergingService = new OrderDataMergingService();
String orderId = dataMergingService.getOrderDataMergingPort()
.importOrder(wsRequest);
Единственный секрет, который я еще не понял, почему я должен публиковать этот сервис OSGi? Потому что при отсутствии службы OSGi (ref="dms" в blueprint.xml) клиент веб-службы не работает.
Ура Йоханнес
Есть ли у вас настоящая война или у вас есть баночка с использованием службы http, покажите, как XML-проект выглядит так, как вы определяете сервлет в XML-проекте. Хотя вы говорите о войне, которая содержит сервлетов и JSP. Помните, что у вас есть два разных расширителя, которые заботятся о сервлете и контексте проекта, оба не могут быть смешаны. Поэтому вам нужно убедиться, что у вас есть способ доступа к контексту пакета из сервлета.
Взгляните на образец белой доски или образец военной весны. Первый использует только план, другой смешивает войну с Spring-DM, который также будет работать с Spring 3.