的Apache CXF拦截器配置

问题描述:

我创建为CXF docs描述的SOAP拦截器:的Apache CXF拦截器配置

public class SoapMessageInterceptor extends AbstractSoapInterceptor { 
    public SoapMessageInterceptor() { 
     super(Phase.USER_PROTOCOL); 
    } 
    public void handleMessage(SoapMessage soapMessage) throws Fault { 
     // ... 
    } 
} 

,并在Spring的应用程序上下文中有公交注册吧:

<cxf:bus> 
    <cxf:inInterceptors> 
     <ref bean="soapMessageInterceptor"/> 
    </cxf:inInterceptors> 
    </cxf:bus> 

    <jaxws:endpoint id="customerWebServiceSoap" 
     implementor="#customerWebServiceSoapEndpoint" 
     address="/customerService"/> 

所有工作正常,直到我添加了一个REST服务:

<jaxrs:server id="customerWebServiceRest" address="/rest"> 
    <jaxrs:serviceBeans> 
     <ref bean="customerWebServiceRestEndpoint" /> 
    </jaxrs:serviceBeans> 
    </jaxrs:server> 

问题在于SOAP拦截器现在也在REST请求上被触发,这导致REST服务被调用时出现类转换异常。

<ns1:XMLFault xmlns:ns1="http://cxf.apache.org/bindings/xformat"> 
    <ns1:faultstring xmlns:ns1="http://cxf.apache.org/bindings/xformat"> 
    java.lang.ClassCastException: org.apache.cxf.message.XMLMessage 
    cannot be cast to org.apache.cxf.binding.soap.SoapMessage 
    </ns1:faultstring> 
</ns1:XMLFault> 

有什么方法可以通过配置将拦截器限制为SOAP消息吗?

更新

看起来像我错过了页面描述这个文档。 向下滚动到Difference between JAXRS filters and CXF interceptors

您可以将拦截到一个单独的端点,而不是公交车:

<jaxws:endpoint id="customerWebServiceSoap" 
    implementor="#customerWebServiceSoapEndpoint" 
    address="/customerService"> 
    <jaxws:inInterceptors> 
    <ref bean="soapMessageInterceptor"/> 
    </jaxws:inInterceptors> 
</jaxws:endpoint> 
+0

但是如果我想在端点之间共享拦截器配置?将它们添加到cxf:bus或jaxws:server不会产生与将它们添加到端点的行为相同的行为。 – Dormouse

你可以尝试配置您的拦截器是这样的:

<cxf:bus name="someBus"> 
    <cxf:inInterceptors> 
     <ref bean="soapMessageInterceptor"/> 
    </cxf:inInterceptors> 
    </cxf:bus> 

通过定义总线,它根据文档的name,标识总线作为一种独特的Spring豆。然后在你的JAX-WS端点配置需要指定总线引用该名称:

<jaxws:endpoint id="customerWebServiceSoap" 
     implementor="#customerWebServiceSoapEndpoint" 
     address="/customerService" 
     bus="someBus"/> 

bus应在此JAX-WS终点才有效。