1

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

到目前为止,我们使用 cxf-codegen maven 插件来创建构建客户端所需的所有类。我们拥有所有依赖项:cxf-rt-transports-httpcxf-rt-ws-addrcxf-rt-ws-policycxf-rt-frontend-jaxrscxf-rt-ws-securitycxf-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" />

当我使用这种方法时,注入失败,因为客户端始终为空。

谁能解释一下如何在 OSGi、蓝图和启用战争的捆绑包中使用 Web 服务客户端?

提前谢谢了。

干杯希尔德里希

4

2 回答 2

2

你有真正的战争还是你有一个使用 http 服务的 jar,因为现在蓝图 xml 看起来就像你在蓝图 xml 中定义了一个 servlet。尽管您谈论的是一场包含 servlet 和 jsps 的战争。请注意,您有两个不同的扩展程序来处理 servlet 和蓝图上下文,两者不能混合使用。所以你需要确保你有一种从 servlet 访问包上下文的方法。

查看whiteboard-blueprint示例或war-spring 示例。第一个仅使用蓝图,另一个将战争与 spring-dm 混合,这也将与 spring 3 一起使用。

于 2013-07-02T06:49:58.073 回答
1

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

首先我的应用程序是一个普通的Java Web Application,即WAR。通过附加的 OSGi Manifest 元数据(Web-ContextPath、Webapp-Context),WAR 被启用为 Web 应用程序包 (WAB)。此外,正如您在上面提到的那样,blueprint.xml没有被 OSGi 容器Apache Karaf识别,因为Blueprint Extender 没有尝试检测Manifest 元数据(Bundle-Blueprint )。

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中运行 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 服务类与blueprint.xml中的真实 Web 服务连接起来,并将其发布为 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 Service:

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

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

干杯约翰内斯

于 2013-07-17T10:19:35.743 回答