如果给定的SOAP标头元素具有给定值(例如,如果标头标记“response”的值为“0”),我不希望Apache CXF返回响应。< / p>
我该怎么做?似乎CXF假设所有呼叫都会收到响应。
(我知道在Web服务上下文中这看起来很奇怪,但如果您的传输是JMS,那就不那么奇怪了。)
答案 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)
<ReplyTo> and <To>
。所以基本上,在场景中你不希望将响应发送给已经请求的客户端,服务器端代码可以改变replyTo字段的值并且可以向虚拟URI发送响应。
答案 3 :(得分:0)
对于您的特定场景,我认为正确的实现方式是使用两个操作。一个用于in-only,另一个用于in-out。
您尝试实施它的方式也可能会导致客户端出现问题。现在,客户端必须根据请求决定是否查找响应。另一方面,由于决策取自客户端客户端发送的值,因此可以决定调用仅进入或进出操作。