3

我创建了一个 SOAP 拦截器,如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 消息?

更新

看起来我错过了描述这一点的文档中的页面。向下滚动到JAXRS 过滤器和 CXF 拦截器之间的区别

4

2 回答 2

11

您可以将拦截器附加到单个端点而不是总线:

<jaxws:endpoint id="customerWebServiceSoap"
    implementor="#customerWebServiceSoapEndpoint"
    address="/customerService">
  <jaxws:inInterceptors>
    <ref bean="soapMessageInterceptor"/>
  </jaxws:inInterceptors>
</jaxws:endpoint>
于 2012-10-12T22:42:31.613 回答
4

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

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

通过定义name总线的 ,根据文档,将总线标识为唯一的Springbean。然后在您的JAX-WS端点配置中,您需要指定引用该名称的总线:

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

bus应该只适用于这个JAX-WS端点。

于 2012-10-12T22:07:03.267 回答