如何使用蓝图构建Web服务客户端

时间:2013-07-01 11:22:32

标签: web-services osgi cxf apache-karaf blueprint-osgi

我们用一个servlet和一个JPS构建了一个WAR,并使用maven bundle插件将其转换成一个bundle。 servlet和jsp在Apache Karaf中使用pax-web正常运行。 现在我想在该servlet中使用Web服务客户端。我怎样才能做到这一点?

到目前为止,我们使用cxf-codegen maven插件来创建构建客户端所需的所有类。 我们拥有所有依赖项: cxf-rt-transports-http cxf-rt-ws-addr cxf-rt-ws-policy cxf-rt-frontend-jaxrs , 在maven中声明的 cxf-rt-ws-security cxf-rt-transports-http-jetty 。此外,我有以下条目 在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,蓝图和中使用Web服务客户端 与战争启用捆绑一起使用?

非常感谢提前。

干杯 Hilderich

2 个答案:

答案 0 :(得分:2)

你有真正的战争,或者你有一个使用http服务的jar,现在就像蓝图xml看起来像在蓝图xml中定义一个servlet一样。虽然你谈论的是包含servlets和jsps的战争。请注意,您有两个不同的扩展器来处理servlet和蓝图上下文,两者都无法混合。因此,您需要确保从servlet访问bundle上下文。

查看whiteboard-blueprint示例或war-spring 样品。第一个只使用蓝图,另一个使用spring-dm混合战争,这也适用于春天3.

答案 1 :(得分:1)

很高兴收到你的来信。与此同时,我对此有了更好的了解 在OSGi容器中运行的Java Web应用程序。

首先,我的应用程序是普通的Java Web应用程序,即WAR。随着 WAR是另外的OSGi Manifest元数据( Web-ContextPath,Webapp-Context ) 已成为Web应用程序包(WAB)。 此外,如上所述,OSGi无法识别 blueprint.xml 容器 Apache Karaf 因为Blueprint Extender试图检测没有Manifest元数据( Bundle-Blueprint )。

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 中运行Web应用程序,您必须安装 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容器(Jetty)都在运行,JSP页面也是如此 正确渲染。

现在我解释如何在Servlet中使用Web Service Client。 使用位于资源目​​录中的WSDL文件,我创建了所有必需的文件 类以构建Web服务客户端。为了轻松做到这一点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>

现在我可以将生成的Web服务类与真实的Web服务连接起来 在 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类和 在远程计算机上调用了Web服务:

OrderDataMergingService dataMergingService = new OrderDataMergingService();
String orderId = dataMergingService.getOrderDataMergingPort()
                .importOrder(wsRequest);

我还没有想到为什么我必须发布OSGi服务? 因为当缺少OSGi服务( blueprint.xml 中的ref =“dms”)时,Web服务客户端不起作用。

干杯 约翰内斯