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

时间:2011-09-27 21:36:07

标签: java web-services jms cxf

如果给定的SOAP标头元素具有给定值(例如,如果标头标记“response”的值为“0”),我不希望Apache CXF返回响应。< / p>

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

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

4 个答案:

答案 0 :(得分:3)

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

我已经使用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:

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

答案 1 :(得分:1)

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

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

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

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

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

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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