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

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

我怎样才能做到这一点? 似乎CXF假设所有呼叫都会收到响应。

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

我已经能够通过一个拦截拦截链的拦截器来做到这一点。

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

package my.super.interceptor; public final class Suppressor extends AbstractSoapInterceptor { public Suppressor() { super(Phase.SETUP); } @Override public void handleMessage(final SoapMessage message) throws Fault { final boolean suppressResponse = this.suppressResponse(message); if(suppressResponse) { log.debug("-> Suppressing response"); message.getInterceptorChain().abort(); } //if you want to suppress both responses and faults, you need //to check them separately. //Change this code to check headers for whatever criteria you want //(Note you may need to change the super(Phase...) ) //The code's a bit messy here - just sketching out the idea for the answer private boolean suppressResponse(final Message message) { final Fault fault = (Fault)message.getContent(Exception.class); if(fault != null) { final String faultMessage = fault.getMessage(); return faultMessage.indexOf("Something-you-want-to-match") > 0; } else { final MessageInfo messageInfo = (MessageInfo)message.get("org.apache.cxf.service.model.MessageInfo"); final String operation = messageInfo.getOperation().getOutputName(); return operation.indexOf("Something-you-want-to-match") > 0; } } 

和您的applicationContext.xml:

         

长解释 :根据SOAP协议规范考虑SOAP Web服务。 Web服务不仅仅是HTTP上的一个奇特层,它实际上是一种描述实现各种消息交换模式的双向通信的方式 。 以下模式是最常见的模式:

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

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

现在重要的部分:在WSDL中,您可以将方法定义为请求/响应(通过定义输入/输出消息)或单向定义(仅通过提供消息)。 这是在服务合同中修复的。 你不能创建一个方法,一旦返回响应( 消息准确),而其他时候不。

显然,您可以定义一个可以为空或包含某些内容的输出消息,但您仍然需要返回一些内容。

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

另一个提示:您可以使用ESB执行某种转换,以便在存在某些SOAP标头时放弃响应。

对于您的特定场景,我认为正确的实现方式是使用两个操作。 一个用于in-only,另一个用于in-out。

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

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