简体   繁体   English

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

[英]How can I prevent Apache CXF from sending a response message?

In cases where a given SOAP header element has a given value (for example, if the value of the header tag "response" is "0"), I don't want Apache CXF to return a response at all. 在给定SOAP头元素具有给定值的情况下(例如,如果头标记“response”的值为“0”),我不希望Apache CXF完全返回响应。

How can I do this? 我怎样才能做到这一点? It appears that CXF makes the assumption that all calls will receive a response. 似乎CXF假设所有呼叫都会收到响应。

(I know this seems strange in a web services context, but if your transport is JMS, it seems less strange). (我知道在Web服务上下文中这似乎很奇怪,但如果你的传输是JMS,那似乎不那么奇怪)。

I've been able to do this with an interceptor that aborts the interceptor chain. 我已经能够通过一个拦截拦截链的拦截器来做到这一点。

I've tested this with an HTTP config (WebSphere returns an empty 200) and an ActiveMQ config (no response comes back to the response queue). 我已经使用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;
     }
   }

and your applicationContext.xml: 和你的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>

Long explanation : think about SOAP web services in terms of SOAP protocol specification. 长解释 :根据SOAP协议规范考虑SOAP Web服务。 Web services is not just a fancy layer on top of HTTP, it is actually a way to describe two-way communication with various message exchange patterns implemented. Web服务不仅仅是HTTP上的一个奇特层,它实际上是一种描述实现各种消息交换模式的双向通信的方式 The following patterns are most common ones: 以下模式是最常见的模式:

  • request-response ( In-Out ): in HTTP environment this is a typical HTTP request/response call with some request message being sent from client to server and some response message is sent back. 请求 - 响应( In-Out ):在HTTP环境中,这是典型的HTTP请求/响应调用,其中一些请求消息从客户端发送到服务器,并且一些响应消息被发回。 In JMS environment you would get two separate and independent messages. 在JMS环境中,您将获得两个独立且独立的消息。

  • one-way ( In-Only ): in this model the client send a request but does not expect nor care about the response. 单向( In-Only ):在此模型中,客户端发送请求但不期望也不关心响应。 In JMS it is equivalent to a simple message sent to the broker. 在JMS中,它相当于发送给代理的简单消息。 In HTTP on the other hand (at least this is how one-way methods are implemented in Apache CXF) you will get a void method on SEI. 另一方面,在HTTP中(至少这是如何在Apache CXF中实现单向方法),您将在SEI上获得一个void方法。 Moreover, CXF by default will use a separate thread pool to handle this request, so the client doesn't even wait for the response and the server is not even able to send that response (because the client might have already disconnected). 此外,默认情况下,CXF将使用单独的线程池来处理此请求,因此客户端甚至不等待响应,并且服务器甚至无法发送该响应(因为客户端可能已经断开连接)。

Now the important part: in WSDL you either define a method as request/response (by defining in/out messages) or as one-way (by only providing in message). 现在重要的部分:在WSDL中,您可以将方法定义为请求/响应(通过定义输入/输出消息)或单向定义(仅通过提供消息)。 This is fixed in service contract. 这是在服务合同中修复的。 You cannot make a method that once returns response ( out message to be precise) while other times it does not. 你不能创建一个方法,一旦返回响应( 消息准确),而其他时候不。

Obviously you can define an out message that can be empty or contain some content, but you still have to return something. 显然,您可以定义一个可以为空或包含某些内容的输出消息,但您仍然需要返回一些内容。

Short explanation : SOAP protocol is not flexible enough to fulfil your requirement. 简短说明 :SOAP协议不够灵活,无法满足您的要求。 You either return a response or not. 你要么回复,要么不回复。 Create two methods and choose which one to call on the client side rather than adding custom headers. 创建两个方法并选择在客户端调用哪个方法而不是添加自定义标头。

Another tip: you might use ESB to perform some sort of transformation so that the response is discarded in presence of some SOAP header. 另一个提示:您可以使用ESB执行某种转换,以便在存在某些SOAP标头时放弃响应。

@Jared: I am mostly agreed with Tomasz's explanation. @Jared:我大多同意Tomasz的解释。 One workaround I can think of lets say if use ws-addressing. 我能想到的一个解决方法就是如果使用ws-addressing。 Ws-addressing allows you to specify <ReplyTo> and <To> . Ws-addressing允许您指定<ReplyTo> and <To> So basically, in scenario you don't want response to be sent to client who has requested, server side code can alter the value of replyTo field and can send response to dummy URI. 所以基本上,在场景中你不希望将响应发送给已经请求的客户端,服务器端代码可以改变replyTo字段的值并且可以向虚拟URI发送响应。

For your particular scenario I think the correct way to implement is to use two operations. 对于您的特定场景,我认为正确的实现方式是使用两个操作。 One for in-only and other for in-out. 一个用于in-only,另一个用于in-out。

The way you try to implement it may cause problems in client side as well. 您尝试实现它的方式也可能导致客户端问题。 now client has to decide whether to look for a response or not depending on the request. 现在,客户端必须根据请求决定是否查找响应。 On the other hand since the decision is taken from a value send by the client at the client side it can decide to invoke the in-only or in-out operation. 另一方面,由于决策取自客户端客户端发送的值,因此可以决定调用仅进入或进出操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Apache CXF:如何从拦截器返回失败响应 - Apache CXF: how to return failure response from an interceptor 如何指定MOXy JAXB作为Apache CXF 2.2.6的Apache CXF实现 - How can I Specify MOXy JAXB as my Apache CXF implementation for Apache CXF 2.2.6 如何在通过JAX-RS(Apache-CXF实现)ExceptionMapper准备的错误响应中保留请求标头 - How can i preserve the request headers in error response prepared through JAX-RS ( Apache-CXF implementation) ExceptionMapper 如何从Apache CXF REST服务返回XML并将其转换为json? - How can I return XML from a Apache CXF REST service and have it converted to json? 如何在TomEE +中配置Apache CXF ignoreNamespaces? - How can I configure Apache CXF ignoreNamespaces in TomEE+? 在Apache CXF Interceptor中编写消息内容和响应代码 - Write message content and response code in Apache CXF Interceptor 使用Apache CXF发送FastInfoset请求时,我可以在日志中使用XML吗? - Can I have the XML in the log when sending FastInfoset request with Apache CXF? 如果最近发送了通知,如何防止再次发送该通知? - How can I prevent a notification from sending again if it was recently sent? Apache CXF(带有spring boot)如何返回原始WSDL文件(不是cxf生成)? - Apache CXF(with spring boot) How can I return original WSDL file(not generated by cxf)? 骆驼Cxf:如何更改传入消息的名称空间? - Camel Cxf: How can I change the namespace of my incoming message?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM