Как создать клиент веб-сервиса с помощью плана

мы создали WAR с одним сервлетом и одним JPS и преобразовали его в пакет с помощью плагина пакета maven. Сервлет и jsp нормально работают в Apache Karaf с pax-web. Теперь я хотел бы использовать клиент веб-службы в этом сервлете. Как я могу этого добиться?

До сих пор мы использовали подключаемый модуль maven cxf-codegen для создания всех необходимых классов для сборки клиента. У нас есть все зависимости: cxf-rt-transports-http, cxf-rt-ws-addr, cxf-rt-ws-policy , cxf-rt-frontend-jaxrs, cxf-rt-ws-security и cxf-rt-transports-http-jetty, объявленные в 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" />

When I use this approach the injection fails because the client is always null.

Может ли кто-нибудь объяснить мне, как клиент веб-службы должен использоваться в OSGi, чертеже и в сочетании с пакетом с поддержкой войны?

Спасибо заранее.

Ура Хильдерих


person Hilde    schedule 01.07.2013    source источник


Ответы (2)


У вас есть настоящая война или у вас есть банка, использующая службу http, потому что сейчас то, как выглядит XML-схема плана, выглядит так, как будто вы определяете сервлет в XML-схеме плана. Хотя вы говорите о войне, которая содержит сервлеты и jsps. Остерегайтесь, что у вас есть два разных расширителя, которые заботятся о сервлете и контексте проекта, оба нельзя смешивать. Поэтому вам нужно убедиться, что у вас есть способ доступа к контексту пакета из сервлета.

Взгляните на whiteboard-blueprint пример или war-spring< /а> образец. Первый использует только план, другой смешивает войну с spring-dm, который также будет работать с Spring 3.

person Achim Nierbeck    schedule 02.07.2013

Приятно слышать от тебя. Тем временем я стал лучше понимать веб-приложения Java, работающие в контейнерах OSGi.

Прежде всего, мое приложение представляет собой обычное веб-приложение Java, то есть WAR. Благодаря дополнительным метаданным манифеста OSGi (Web-ContextPath, Webapp-Context) WAR стал пакетом веб-приложений (WAB). Кроме того, как вы упомянули выше, blueprint.xml не был распознан OSGi-контейнером Apache Karaf из-за отсутствия метаданных манифеста (Bundle-Blueprint >) Blueprint Extender пытается обнаружить.

Плагин пакета maven (то есть инструмент 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

При этом сервлет-контейнер (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) отсутствует, клиент веб-службы не работает.

Ура Йоханнес

person Hilde    schedule 17.07.2013