Java 如何防止Apache CXF发送响应消息?

Java 如何防止Apache CXF发送响应消息?,java,web-services,jms,cxf,Java,Web Services,Jms,Cxf,在给定SOAP头元素具有给定值的情况下(例如,如果头标记“response”的值为“0”),我根本不希望Apache CXF返回响应 我该怎么做?似乎CXF假设所有呼叫都将收到响应 (我知道这在web服务上下文中似乎很奇怪,但如果您的传输是JMS,那么就不那么奇怪了)。详细解释:从SOAP协议规范的角度考虑SOAP web服务。Web服务不仅仅是HTTP之上的一个奇特的层,它实际上是一种描述各种实现的双向通信的方法。以下是最常见的模式: 请求-响应(In-Out):在HTTP环境中,这是一个典

在给定SOAP头元素具有给定值的情况下(例如,如果头标记“response”的值为“0”),我根本不希望Apache CXF返回响应

我该怎么做?似乎CXF假设所有呼叫都将收到响应


(我知道这在web服务上下文中似乎很奇怪,但如果您的传输是JMS,那么就不那么奇怪了)。

详细解释:从SOAP协议规范的角度考虑SOAP web服务。Web服务不仅仅是HTTP之上的一个奇特的层,它实际上是一种描述各种实现的双向通信的方法。以下是最常见的模式:

  • 请求-响应(In-Out):在HTTP环境中,这是一个典型的HTTP请求/响应调用,其中一些请求消息从客户端发送到服务器,一些响应消息被发送回。在JMS环境中,您将获得两条独立的消息

  • 单向(仅适用于):在此模型中,客户端发送请求,但不期望也不关心响应。在JMS中,它相当于发送给代理的简单消息。另一方面,在HTTP中(至少在apachecxf中单向方法是这样实现的),您将在SEI上获得一个
    void
    方法。此外,默认情况下,CXF将使用单独的线程池来处理该请求,因此客户端甚至不等待响应,服务器甚至无法发送该响应(因为客户端可能已经断开连接)

现在是重要的部分:在WSDL中,您可以将方法定义为请求/响应(通过定义in/out消息)或单向(通过仅提供in消息)。这在服务合同中是固定的。您不能使一个方法一次返回响应(准确地说是输出消息),而另一次不返回响应

显然,您可以定义一个out消息,该消息可以是空的,也可以包含一些内容,但您仍然必须返回一些内容

简短解释:SOAP协议不够灵活,无法满足您的要求。您要么返回响应,要么不返回响应。创建两个方法,并选择在客户端调用哪个方法,而不是添加自定义头


另一个技巧:您可以使用ESB执行某种类型的转换,以便在存在某个SOAP头时丢弃响应。

@Jared:我基本上同意Tomasz的解释。我能想到的一个解决方法是,假设使用ws-addressing。Ws-addressing允许您指定
。所以,基本上,在您不希望将响应发送给请求的客户机的场景中,服务器端代码可以更改replyTo字段的值,并可以将响应发送到虚拟URI

对于您的特定场景,我认为正确的实现方法是使用两个操作。一个仅用于输入,另一个用于输入输出


您尝试实现它的方式也可能导致客户端出现问题。现在,客户端必须根据请求决定是否寻找响应。另一方面,由于决策来自客户端客户端发送的值,因此它可以决定调用in only或in out操作

我已经能够通过中断拦截器链的拦截器来实现这一点

我已经用HTTP配置(WebSphere返回空200)和ActiveMQ配置(没有响应返回到响应队列)对此进行了测试

以及您的applicationContext.xml:

<jaxws:endpoint ...>
  <jaxws:outInterceptors>
     <bean class="my.super.interceptor.Suppressor"/>
   </jaxws:outInterceptors>
   <jaxws:outFaultInterceptors>
     <bean class="my.super.interceptor.Suppressor"/>
   </jaxws:outFaultInterceptors>
</jaxws:endpoint>


我考虑过使用重复的操作定义(请求-响应定义和单向定义),但这不能很好地扩展到数十个或数百个服务(它使您必须实现的服务数量增加了一倍)。我还考虑了基于ESB的解决方案,但关键是要消除发布响应所增加的开销。我仍然会将响应推送到ESB层,只是为了丢弃它们。
<jaxws:endpoint ...>
  <jaxws:outInterceptors>
     <bean class="my.super.interceptor.Suppressor"/>
   </jaxws:outInterceptors>
   <jaxws:outFaultInterceptors>
     <bean class="my.super.interceptor.Suppressor"/>
   </jaxws:outFaultInterceptors>
</jaxws:endpoint>