diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/SplitterFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/SplitterFactoryBean.java index 706dd8095a..dbae530ef5 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/SplitterFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/SplitterFactoryBean.java @@ -31,6 +31,7 @@ import org.springframework.util.StringUtils; public class SplitterFactoryBean extends AbstractMessageHandlerFactoryBean { private volatile Long sendTimeout; + private volatile boolean requiresReply; public void setSendTimeout(Long sendTimeout) { this.sendTimeout = sendTimeout; @@ -64,7 +65,14 @@ public class SplitterFactoryBean extends AbstractMessageHandlerFactoryBean { if (this.sendTimeout != null) { splitter.setSendTimeout(sendTimeout); } + splitter.setRequiresReply(requiresReply); return splitter; } + public boolean isRequiresReply() { + return requiresReply; + } + public void setRequiresReply(boolean requiresReply) { + this.requiresReply = requiresReply; + } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/splitter/AbstractMessageSplitter.java b/spring-integration-core/src/main/java/org/springframework/integration/splitter/AbstractMessageSplitter.java index 161c6c8b47..a53added58 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/splitter/AbstractMessageSplitter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/splitter/AbstractMessageSplitter.java @@ -20,7 +20,10 @@ import org.springframework.integration.Message; import org.springframework.integration.MessageHeaders; import org.springframework.integration.handler.AbstractReplyProducingMessageHandler; import org.springframework.integration.support.MessageBuilder; +import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; +import java.lang.reflect.Array; import java.util.*; /** @@ -38,7 +41,10 @@ public abstract class AbstractMessageSplitter extends AbstractReplyProducingMess @SuppressWarnings("unchecked") protected final Object handleRequestMessage(Message message) { Object result = this.splitMessage(message); - if (result == null) { + // return null if 'null', empty Collection or empty Array + if ( result == null || + (result instanceof Collection && CollectionUtils.isEmpty((Collection)result)) || + (result.getClass().isArray() && ObjectUtils.isEmpty((Object[]) result)) ) { return null; } MessageHeaders headers = message.getHeaders(); @@ -59,10 +65,6 @@ public abstract class AbstractMessageSplitter extends AbstractReplyProducingMess List> messageBuilders = new ArrayList>(); if (result instanceof Collection) { Collection items = (Collection) result; - //TODO put this return statement in a more obvious place - if(items.isEmpty()){ - return null; - } int sequenceNumber = 0; int sequenceSize = items.size(); for (Object item : items) { diff --git a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd index 760f660fc3..7066cebf9b 100644 --- a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd +++ b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd @@ -1948,6 +1948,15 @@ Name of the header whose value to use. + + + + Specify whether the splitter method must return a non-null value. This value will be + FALSE by default, but if set to TRUE, a MessageHandlingException will be thrown when + the underlying service method (or expression) returns a NULL value. + + + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/config/SplitterParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/router/config/SplitterParserTests.java index 3a795055c8..8e13d1a5d6 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/router/config/SplitterParserTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/config/SplitterParserTests.java @@ -19,13 +19,19 @@ package org.springframework.integration.router.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import java.util.Collections; + import org.junit.Test; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.Message; import org.springframework.integration.MessageChannel; +import org.springframework.integration.MessageHandlingException; +import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.core.PollableChannel; +import org.springframework.integration.endpoint.EventDrivenConsumer; import org.springframework.integration.message.GenericMessage; +import org.springframework.integration.support.MessageBuilder; /** * @author Mark Fisher @@ -88,5 +94,14 @@ public class SplitterParserTests { assertEquals("test", result4.getPayload()); assertNull(output.receive(0)); } + + @Test(expected=MessageHandlingException.class) + public void splitterParserTestWithRequiresReply() { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "splitterParserTests.xml", this.getClass()); + context.start(); + DirectChannel inputChannel = context.getBean("requiresReplyInput", DirectChannel.class); + inputChannel.send(MessageBuilder.withPayload(Collections.emptyList()).build()); + } } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterParserTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterParserTests.xml index 190a41014b..aa96b3df2b 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterParserTests.xml +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterParserTests.xml @@ -26,6 +26,11 @@ ref="splitterImpl" input-channel="splitterImplementationInput" output-channel="output"/> + + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/splitter/DefaultSplitterTests.java b/spring-integration-core/src/test/java/org/springframework/integration/splitter/DefaultSplitterTests.java index e2326ec28a..bcfafb3f93 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/splitter/DefaultSplitterTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/splitter/DefaultSplitterTests.java @@ -16,6 +16,17 @@ package org.springframework.integration.splitter; +import static junit.framework.Assert.assertEquals; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + import org.junit.Test; import org.springframework.integration.Message; import org.springframework.integration.channel.DirectChannel; @@ -23,15 +34,6 @@ import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.endpoint.EventDrivenConsumer; import org.springframework.integration.support.MessageBuilder; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static junit.framework.Assert.assertEquals; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.*; - /** * @author Mark Fisher * @author Iwein Fuld @@ -104,5 +106,4 @@ public class DefaultSplitterTests { Message output = replyChannel.receive(15); assertThat(output, is(nullValue())); } - }