我使用spring集成框架连接到一些旧的服务器套接字。
以下是我的客户端工厂和适配器:
<int-ip:tcp-connection-factory id="client"
type="client"
host="${tcpServer}"
port="${tcpPort}"
single-use="false"
using-nio="false" />
<int-ip:tcp-inbound-channel-adapter id="inboundServer"
client-mode="true"
channel="inputStream"
error-channel="errorChannel"
retry-interval="${retryInterval}"
connection-factory="client" />
在流到字符串转换器下方:
<int:transformer id="clientBytes2String"
input-channel="inputStream"
output-channel="inputString"
expression="new String(payload)" />
<int:channel id="inputString" />
以下部分是空的,因为我不确定在这里实施什么,所以它可以调用我的路由器和路由器来完成它的业务。
我尝试使用分离器,它确实有效,如果流的格式为“ABCD EFGH WXYZ”或“ABCD”,但如果流程像“ABCD XXXX EFGH WXYZ”那样则失败。期望的结果是它应该处理3个消息和1个错误。但相反,它处理了1条消息,所有其余的都被忽略了。
以下代码:
<int:splitter input-channel="inputString"
output-channel="preRouter2"
method="splitMessage"
ref="messageSplitterBean"/>
MessageSpliterBean类如下:
@Splitter
public List<Message<?>> splitMessage( Message<?> message ) {
List<Message<?>> msgFragments = new ArrayList<Message<?>>();
//Let say I am assuming message will be coming ABCD EFGH WXYZ
String str[] = message.getPayload().toString().split(" ");
int counter = 1;
for ( String s : str ) {
Message<String> resultMessage = MessageBuilder.withPayload( s )
.copyHeaders(message.getHeaders())
.build();
msgFragments.add(resultMessage);
}
return msgFragments;
}
以下将是我的路由器,它将根据某些表达式发送到相应的频道:
<int:recipient-list-router id="customRouter" input-channel="preRouter2">
<int:recipient channel="input1" selector-expression="payload.toString().startsWith('ABCD')"/>
<int:recipient channel="input2" selector-expression="payload.toString().startsWith('EFGH')"/>
<int:recipient channel="input3" selector-expression="payload.toString().startsWith('WXYZ')"/>
需要你的专家观点:我做错了什么,或者什么是最好的方法。
服务器套接字的输入将是固定长度和空格作为分隔符的数据流。每个固定长度,我需要将它们转换成一个消息,并将其发送到相关的频道。
问候。
答案 0 :(得分:0)
首先没有理由实施您自己的Splitter
,因为默认选项有delimiters
选项:
我的另一点是关于<int:transformer>
的冗余byte[] -> String
。 Spring Integration为您提供了开箱即用的ObjectToStringTransformer
。
您的问题是<int:recipient-list-router>
。正如您所说,您的数据可能有问题,而router
尚未准备好处理此类消息,而且您的数据无效。那只是因为(AbstractMessageRouter
):
else {
throw new MessageDeliveryException(message, "No channel resolved by router '" + this.getComponentName()
+ "' and no 'defaultOutputChannel' defined.");
}
当没有人selector-expression
接受您错误的讯息时会发生这种情况。
在这种情况下,它会发送到error-channel="errorChannel"
上的<int-ip:tcp-inbound-channel-adapter>
,并且会因为MessageDeliveryException
而停止进一步的处理。
如您所见,您似乎要解决问题,应将default-output-channel
添加到recipient-list-router
配置中。