使用MarshallingWebServiceOutboundGateway时选择正确的SoapAction

时间:2016-12-21 22:50:05

标签: spring-integration soap-client

我正在尝试学习Spring Integration。作为探索所有功能的测试项目。我的项目就像这样

AMQP Queue -> Header Router -> Transformer -> OutBound SOAP WS Call -> Log Results -> End

1。)通过侦听RabbitMq队列启动流程。发送的RabbitMq消息将具有字符串值(例如:32)和类似{“operation”“CelsiusToFahrenheit”}的标题。

2.)然后,RabbitMq消息将根据RabbitMQ标头值(“操作”)转换为相应的Java对象。

3.)然后我使用MarshallingWebServiceOutboundGateway来调用SOAP WebService @(http://www.w3schools.com/xml/tempconvert.asmx)。当我这样做时,我得到一个错误。

  

ErrorMessage [payload = org.springframework.messaging.MessageHandlingException:消息处理程序[wsOutboundGateway]发生错误;嵌套异常是org.springframework.ws.soap.client.SoapFaultClientException:服务器无法识别HTTP标头SOAPAction的值:。,headers = {replyChannel = org.springframework.messaging.core.GenericMessagingTemplate $ TemporaryReplyChannel @ 601affec,errorChannel = org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@601affec,id = 7f6624cc-e7a4-37f6-0a1f-578dc78c4afa,timestamp = 1482356790717}]

正如您所看到的,SOAPAction为空,服务器不喜欢它。

如果我像这样硬编码SOAPAction

public MessageHandler wsOutboundGateway()
{
    MarshallingWebServiceOutboundGateway temperatureConversionWebServiceGateway = new MarshallingWebServiceOutboundGateway(WEBSERVICE_URL, jaxb2Marshaller(), jaxb2Marshaller());
    temperatureConversionWebServiceGateway.setRequestCallback(new SoapActionCallback("http://www.w3schools.com/xml/CelsiusToFahrenheit"));
    temperatureConversionWebServiceGateway.setOutputChannelName("webServiceResponseChannel");
    return temperatureConversionWebServiceGateway;
}

它有效!

但是,端点会公开2个服务(2个可能的操作)。见下文。

  

FahrenheitToCelsius soapAction =“http://www.w3schools.com/xml/FahrenheitToCelsius”   CelsiusToFahrenheit soapAction =“http://www.w3schools.com/xml/CelsiusToFahrenheit”

我希望能够在运行时根据RabbitMQ标头值(“操作”)设置SoapAction。我该怎么做?

在附注中,我已经做了一些不同的实验来解决这个问题,但似乎没有人能够得到我想要的结果。我尝试的解决方案之一是将SoapAction设置为转换过程的一部分(将输入从Rabbit MQ消息转换为基于RabbitMQ标头值的相应Java类型)并将该请求发送到出站网关(请参阅下面的代码)

@Bean
public IntegrationFlow generateCelsiusToFahrenheitRequestFlow() {

    Map<String, Object> headers = new HashMap<>();
    headers.put("SOAPAction", "http://www.w3schools.com/xml/CelsiusToFahrenheit");

    return IntegrationFlows.from(celsiusToFahrenheitChannel)
            .transform(celsiusToFahrenheitTransformer)
            .enrichHeaders(headers)
            .channel(webServiceRequestChannel)
            .get();
}

在我这样做并点击'webServiceRequestChannel'之后,我看到了之前添加的SoapAction标题(见下文)。

  

GenericMessage [payload = CelsiusToFahrenheit [celsius = 32],headers = {SOAPAction = http://www.w3schools.com/xml/CelsiusToFahrenheit,amqp_receivedDeliveryMode = NON_PERSISTENT,........

但是,当MarshallingWebServiceOutboundGateway选择请求并对SOAP WebService进行出站调用时,“SOAPAction:”仍为空。我不知道为什么Soap Action被淘汰了。我错过了什么?

很抱歉,如果我在编写/格式化问题时没有遵循惯例。这是我第一次参加Stack Overflow。任何有关解决这一问题的意见或建议都将受到极大关注。

1 个答案:

答案 0 :(得分:2)

是的,这里的错误是标题名称必须是ws_soapAction,其名称为DefaultSoapHeaderMapper。只有现在WebserviceMessage才能将其映射到请求public DefaultSoapHeaderMapper() { super(WebServiceHeaders.PREFIX, STANDARD_HEADER_NAMES, Collections.<String>emptyList()); }

RewriteRule    ^/v10/(.*) /v11/$1 [R]