[英]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.