2013-04-18 77 views
1

我有多個WAR,它們都使用CXFServlet來處理所有請求和Spring配置。多個CXF服務器綁定被第一臺服務器覆蓋

他們都有着相似的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,Karaf:2.3.1

回答

1

如果你在裏面Karaf運行,我建議先安裝CXF的功能之後,僅僅註冊您的CXF端點通過藍圖,就像使用Apache Camel完成一樣。由於我的知識,CXF確實在cxf上下文中註冊了一個「主」servlet,從那裏可以訪問所有web服務。 在這一點上,你不需要任何戰爭。除此之外,您並未顯示有關Web-ContextPath的清單條目,因此Web容器在可服務條件之間有所不同,因此如果它們都具有相同的上下文,那麼第一條就會勝出!

+0

感謝您的回答!我知道這個版本的'CXF'具有的「主」servlet。然而,我正從'CXF 2.4.2'遷移並使用'WARs'和Spring Web上下文,所以轉向您所建議的解決方案,這是正確的,在我的應用程序中需要進行太多的更改和一步操作。因此,我決定保留'WARs',雖然沒有明確說明,但每個都有不同的'Web-ContextPath'值。我能找到一個解決方案,我將發佈一個單獨的答案。 – Roadrunner

0

原來這是DestinationRegistry的問題。默認情況下,CXF註冊一個DestinationFactory,它使用單個實例DestinationRegistry。這就是爲什麼每個Server被分配到單個Destination,因爲如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結合使用SpringBus作爲ConfiguredBeanLocator結果在一個單獨的Spring管理的每各WAR捆HTTP DestinationRegistry的情況下,這反過來又允許aproper配置每個包中的CXF服務器並導致適當的應用程序。

+0

你有沒有可能將我指向這個示例代碼的方向?你如何配置'SpringBeanLocator'來找到'DestinationRegistryImpl'? – zode64