Apache CXF拦截器配置

时间:2012-10-12 19:47:50

标签: java spring jax-ws cxf jax-rs

我创建了一个SOAP拦截器,如CXF docs

中所述
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

2 个答案:

答案 0 :(得分:10)

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

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

答案 1 :(得分:4)

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

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

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

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

bus应仅适用于此JAX-WS端点。