INT-630 Web Service outbound gateways now support a boolean 'ignore-empty-responses' attribute, and the default value is TRUE.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,6 +25,7 @@ import org.springframework.integration.handler.AbstractReplyProducingMessageHand
|
||||
import org.springframework.integration.handler.ReplyMessageHolder;
|
||||
import org.springframework.integration.ws.destination.MessageAwareDestinationProvider;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.WebServiceMessageFactory;
|
||||
import org.springframework.ws.client.core.FaultMessageResolver;
|
||||
@@ -38,6 +39,7 @@ import org.springframework.ws.transport.WebServiceMessageSender;
|
||||
* Base class for outbound Web Service-invoking Messaging Gateways.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Jonas Partner
|
||||
*/
|
||||
public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyProducingMessageHandler {
|
||||
|
||||
@@ -45,7 +47,9 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
|
||||
|
||||
private volatile WebServiceMessageCallback requestCallback;
|
||||
|
||||
private final MessageAwareDestinationProvider destinationProvider;
|
||||
private final MessageAwareDestinationProvider destinationProvider;
|
||||
|
||||
private volatile boolean ignoreEmptyResponses = true;
|
||||
|
||||
|
||||
public AbstractWebServiceOutboundGateway(MessageAwareDestinationProvider destinationProvider, WebServiceMessageFactory messageFactory) {
|
||||
@@ -60,6 +64,15 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
|
||||
this.setOutputChannel(replyChannel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether empty String response payloads should be ignored.
|
||||
* The default is <code>true</code>. Set this to <code>false</code> if
|
||||
* you want to send empty String responses in reply Messages.
|
||||
*/
|
||||
public void setIgnoreEmptyResponses(boolean ignoreEmptyResponses) {
|
||||
this.ignoreEmptyResponses = ignoreEmptyResponses;
|
||||
}
|
||||
|
||||
public void setMessageFactory(WebServiceMessageFactory messageFactory) {
|
||||
this.webServiceTemplate.setMessageFactory(messageFactory);
|
||||
}
|
||||
@@ -90,9 +103,14 @@ public abstract class AbstractWebServiceOutboundGateway extends AbstractReplyPro
|
||||
|
||||
@Override
|
||||
public final void handleRequestMessage(Message<?> message, ReplyMessageHolder replyHolder) {
|
||||
Object responsePayload = this.doHandle(message.getPayload(), this.getRequestCallback(message),this.getDestinationProvider().getDestination(message));
|
||||
Object responsePayload = this.doHandle(message.getPayload(),
|
||||
this.getRequestCallback(message), this.getDestinationProvider().getDestination(message));
|
||||
if (responsePayload != null) {
|
||||
replyHolder.set(responsePayload);
|
||||
boolean shouldIgnore = (this.ignoreEmptyResponses
|
||||
&& responsePayload instanceof String && !StringUtils.hasText((String) responsePayload));
|
||||
if (!shouldIgnore) {
|
||||
replyHolder.set(responsePayload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,18 +21,20 @@ import org.w3c.dom.Element;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.adapter.config.AbstractRemotingOutboundGatewayParser;
|
||||
import org.springframework.integration.ws.destination.MessageAwareDestinationProvider;
|
||||
import org.springframework.integration.ws.destination.HeaderBasedDestinationProvider;
|
||||
import org.springframework.integration.ws.destination.FixedUriDestinationProvider;
|
||||
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Parser for the <outbound-gateway/> element in the 'ws' namespace.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Jonas Partner
|
||||
*/
|
||||
public class WebServiceOutboundGatewayParser extends AbstractRemotingOutboundGatewayParser {
|
||||
|
||||
private static final String BASE_PACKAGE = "org.springframework.integration.ws";
|
||||
|
||||
|
||||
@Override
|
||||
protected String getGatewayClassName(Element element) {
|
||||
String simpleClassName = (StringUtils.hasText(element.getAttribute("marshaller"))) ?
|
||||
@@ -47,38 +49,37 @@ public class WebServiceOutboundGatewayParser extends AbstractRemotingOutboundGat
|
||||
String destinationProvider = element.getAttribute("destination-provider");
|
||||
|
||||
if (StringUtils.hasText(destinationProvider) && (StringUtils.hasText(uri) || StringUtils.hasText(uriHeader))) {
|
||||
parserContext.getReaderContext().error("The 'uri' and/or 'uri-header' can not be specified if setting destination-provider.", element);
|
||||
parserContext.getReaderContext().error("The 'uri' and/or 'uri-header' are not allowed if setting destination-provider.", element);
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(destinationProvider) && !(StringUtils.hasText(uri) || StringUtils.hasText(uriHeader))) {
|
||||
parserContext.getReaderContext().error("The at least one of 'uri' or 'uri-header' must be specified if not setting destination-provider.", element);
|
||||
parserContext.getReaderContext().error("At least one of 'uri' or 'uri-header' must be specified if not setting destination-provider.", element);
|
||||
}
|
||||
|
||||
if(StringUtils.hasText(destinationProvider)){
|
||||
if (StringUtils.hasText(destinationProvider)) {
|
||||
builder.addConstructorArgReference(destinationProvider);
|
||||
} else if (StringUtils.hasText(uri) && ! StringUtils.hasText(uriHeader)){
|
||||
BeanDefinitionBuilder destinationProviderBuilder = BeanDefinitionBuilder.genericBeanDefinition(FixedUriDestinationProvider.class);
|
||||
}
|
||||
else if (StringUtils.hasText(uri) && ! StringUtils.hasText(uriHeader)) {
|
||||
BeanDefinitionBuilder destinationProviderBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
BASE_PACKAGE + ".destination.FixedUriDestinationProvider");
|
||||
destinationProviderBuilder.getBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(0, uri);
|
||||
builder.addConstructorArgValue(destinationProviderBuilder.getBeanDefinition());
|
||||
}else{
|
||||
BeanDefinitionBuilder destinationProviderBuilder = BeanDefinitionBuilder.genericBeanDefinition(HeaderBasedDestinationProvider.class);
|
||||
}
|
||||
else {
|
||||
BeanDefinitionBuilder destinationProviderBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
BASE_PACKAGE + ".destination.HeaderBasedDestinationProvider");
|
||||
destinationProviderBuilder.getBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(0, uri);
|
||||
destinationProviderBuilder.getBeanDefinition().getConstructorArgumentValues().addIndexedArgumentValue(1, uriHeader);
|
||||
builder.addConstructorArgValue(destinationProviderBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(this.getGatewayClassName(element));
|
||||
this.buildDestinationProvider(element, parserContext,builder);
|
||||
|
||||
String replyChannel = element.getAttribute("reply-channel");
|
||||
if (StringUtils.hasText(replyChannel)) {
|
||||
builder.addPropertyReference("replyChannel", replyChannel);
|
||||
}
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "ignore-empty-responses");
|
||||
this.postProcessGateway(builder, element, parserContext);
|
||||
return builder;
|
||||
}
|
||||
@@ -118,7 +119,7 @@ public class WebServiceOutboundGatewayParser extends AbstractRemotingOutboundGat
|
||||
String messageSenderListRef = element.getAttribute("message-senders");
|
||||
if (StringUtils.hasText(messageSenderRef) && StringUtils.hasText(messageSenderListRef)) {
|
||||
parserContext.getReaderContext().error(
|
||||
"Only one of message-sender or message-senders should be specified", element);
|
||||
"Only one of message-sender or message-senders should be specified.", element);
|
||||
}
|
||||
if (StringUtils.hasText(messageSenderRef)) {
|
||||
builder.addPropertyReference("messageSender", messageSenderRef);
|
||||
|
||||
@@ -75,7 +75,15 @@
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="ignore-empty-responses" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Indicates whether empty String response payloads should be ignored. The default is TRUE.
|
||||
Set this to FALSE if you want to send empty String responses in reply Messages.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="source-extractor" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -43,6 +43,43 @@ import org.springframework.ws.transport.WebServiceMessageSender;
|
||||
*/
|
||||
public class WebServiceOutboundGatewayParserTests {
|
||||
|
||||
@Test
|
||||
public void simpleGatewayWithReplyChannel() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"simpleWebServiceOutboundGatewayParserTests.xml", this.getClass());
|
||||
AbstractEndpoint endpoint = (AbstractEndpoint) context.getBean("gatewayWithReplyChannel");
|
||||
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
|
||||
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
|
||||
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
|
||||
Object expected = context.getBean("outputChannel");
|
||||
assertEquals(expected, accessor.getPropertyValue("outputChannel"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleGatewayWithIgnoreEmptyResponseTrueByDefault() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"simpleWebServiceOutboundGatewayParserTests.xml", this.getClass());
|
||||
AbstractEndpoint endpoint = (AbstractEndpoint) context.getBean("gatewayWithReplyChannel");
|
||||
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
|
||||
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
|
||||
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
|
||||
assertEquals(Boolean.TRUE, accessor.getPropertyValue("ignoreEmptyResponses"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleGatewayWithIgnoreEmptyResponses() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"simpleWebServiceOutboundGatewayParserTests.xml", this.getClass());
|
||||
AbstractEndpoint endpoint = (AbstractEndpoint) context.getBean("gatewayWithIgnoreEmptyResponsesFalse");
|
||||
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
|
||||
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
|
||||
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
|
||||
assertEquals(Boolean.FALSE, accessor.getPropertyValue("ignoreEmptyResponses"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleGatewayWithDefaultSourceExtractor() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
|
||||
@@ -19,6 +19,20 @@
|
||||
<si:queue capacity="10"/>
|
||||
</si:channel>
|
||||
|
||||
<si:channel id="outputChannel">
|
||||
<si:queue capacity="10"/>
|
||||
</si:channel>
|
||||
|
||||
<ws:outbound-gateway id="gatewayWithReplyChannel"
|
||||
request-channel="inputChannel"
|
||||
uri="http://example.org"
|
||||
reply-channel="outputChannel"/>
|
||||
|
||||
<ws:outbound-gateway id="gatewayWithIgnoreEmptyResponsesFalse"
|
||||
request-channel="inputChannel"
|
||||
uri="http://example.org"
|
||||
ignore-empty-responses="false"/>
|
||||
|
||||
<ws:outbound-gateway id="gatewayWithDefaultSourceExtractor"
|
||||
request-channel="inputChannel"
|
||||
uri="http://example.org"/>
|
||||
|
||||
Reference in New Issue
Block a user