1

我有多个WARs 都使用 aCXFServlet来处理所有请求和Spring配置。

他们都有一个相似的web.xml(是的,它OSGi也在):

<web-app id="app1">
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:META-INF/spring/*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>app1</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>app1</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

它们都共享一个共同的Spring配置(common-rest.xml):

<beans>
    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <!-- For brevity I left out jaxRSProviders and jaxRSInInterceptors lists definitions -->    
    <bean id="baseJaxRSServer"
        abstract="true"
        lazy-init="false"
        class="org.apache.cxf.jaxrs.spring.JAXRSServerFactoryBeanDefinitionParser.SpringJAXRSServerFactoryBean"
        init-method="create"
        p:address="${http.server}/"
        p:providers-ref="jaxRSProviders"
        p:inInterceptors-ref="jaxRSInInterceptors" />
</beans>

它们都具有类似的特定Spring配置:

<beans>
    <import resource="classpath:META-INF/app/common-rest.xml" />
    <!-- For brevity I left out app1ServiceBeans list definition -->    
    <bean id="app1JaxRSServer"
        parent="baseJaxRSServer"
        p:serviceBeans-ref="app1ServiceBeans" />
</beans>

问题是,当我现在部署第一个应用程序时,它看起来还不错,但是基本上看不到所有其他应用程序绑定。似乎尽管所有应用程序都有单独的Spring上下文和单独的CXF服务器和单独的CXF总线,但它们仍然不知何故会感到困惑,并且每个应用程序都被分配了一个org.apache.cxf.transport.Destination- 来自第一个捆绑包的那个。有谁知道这怎么可能?

CXF:2.6.2,弹簧:3.1.4,卡拉夫:2.3.1

4

2 回答 2

1

如果您在 Karaf 中运行,我建议您首先安装 cxf 功能,然后通过蓝图注册您的 cxf 端点,就像使用 Apache Camel 一样。因为据我所知,CXF 确实在 cxf 上下文中注册了一个“主”servlet,从那里可以访问所有 web 服务。在这一点上,你不需要任何战争。除了您没有显示有关 Web-ContextPath 的清单条目之外,Web 容器需要在可服务的上下文之间进行区分,因此如果它们都具有相同的上下文,则第一个获胜!

于 2013-04-19T06:45:08.950 回答
0

原来这是一个问题DestinationRegistry。默认情况下,CXF注册一个DestinationFactory使用DestinationRegistry. 这就是为什么每个都Server被分配给一个Destination,因为它们都被映射到/每个 servlet,正如address字段值所定义的那样。

对我有用的解决方案是为每个WAR捆绑包添加一个单独的目标注册表。所以我common-rest.xml现在看起来像这样:

<beans>
    <import resource="classpath:META-INF/cxf/cxf.xml" />

    <bean id="httpDestinationRegistry"
        class="org.apache.cxf.transport.http.DestinationRegistryImpl" />

    <!-- For brevity I left out jaxRSProviders and jaxRSInInterceptors lists definitions -->    
    <bean id="baseJaxRSServer"
        abstract="true"
        lazy-init="false"
        class="org.apache.cxf.jaxrs.spring.JAXRSServerFactoryBeanDefinitionParser.SpringJAXRSServerFactoryBean"
        init-method="create"
        p:address="${http.server}/"
        p:providers-ref="jaxRSProviders"
        p:inInterceptors-ref="jaxRSInInterceptors" />
</beans>

上述配置结合SpringBeanLocator使用SpringBusConfiguredBeanLocator结果为每个 WAR 捆绑包生成一个单独的 Spring 托管 HTTP 实例DestinationRegistry,这反过来又允许在每个捆绑包中正确配置 CXF 服务器并生成正确的应用程序。

于 2013-04-22T12:24:34.243 回答