簡體   English   中英

如何防止Apache CXF發送響應消息?

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

在給定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:

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

長解釋 :根據SOAP協議規范考慮SOAP Web服務。 Web服務不僅僅是HTTP上的一個奇特層,它實際上是一種描述實現各種消息交換模式的雙向通信的方式 以下模式是最常見的模式:

  • 請求 - 響應( In-Out ):在HTTP環境中,這是典型的HTTP請求/響應調用,其中一些請求消息從客戶端發送到服務器,並且一些響應消息被發回。 在JMS環境中,您將獲得兩個獨立且獨立的消息。

  • 單向( In-Only ):在此模型中,客戶端發送請求但不期望也不關心響應。 在JMS中,它相當於發送給代理的簡單消息。 另一方面,在HTTP中(至少這是如何在Apache CXF中實現單向方法),您將在SEI上獲得一個void方法。 此外,默認情況下,CXF將使用單獨的線程池來處理此請求,因此客戶端甚至不等待響應,並且服務器甚至無法發送該響應(因為客戶端可能已經斷開連接)。

現在重要的部分:在WSDL中,您可以將方法定義為請求/響應(通過定義輸入/輸出消息)或單向定義(僅通過提供消息)。 這是在服務合同中修復的。 你不能創建一個方法,一旦返回響應( 消息准確),而其他時候不。

顯然,您可以定義一個可以為空或包含某些內容的輸出消息,但您仍然需要返回一些內容。

簡短說明 :SOAP協議不夠靈活,無法滿足您的要求。 你要么回復,要么不回復。 創建兩個方法並選擇在客戶端調用哪個方法而不是添加自定義標頭。

另一個提示:您可以使用ESB執行某種轉換,以便在存在某些SOAP標頭時放棄響應。

@Jared:我大多同意Tomasz的解釋。 我能想到的一個解決方法就是如果使用ws-addressing。 Ws-addressing允許您指定<ReplyTo> and <To> 所以基本上,在場景中你不希望將響應發送給已經請求的客戶端,服務器端代碼可以改變replyTo字段的值並且可以向虛擬URI發送響應。

對於您的特定場景,我認為正確的實現方式是使用兩個操作。 一個用於in-only,另一個用於in-out。

您嘗試實現它的方式也可能導致客戶端問題。 現在,客戶端必須根據請求決定是否查找響應。 另一方面,由於決策取自客戶端客戶端發送的值,因此可以決定調用僅進入或進出操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM