Spring Integration 3.0版:根据内容将TCP流消息拆分为多个消息

时间:2015-08-23 13:59:32

标签: java spring tcp spring-integration splitter

我使用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" />

以下部分是空的,因为我不确定在这里实施什么,所以它可以调用我的路由器和路由器来完成它的业务。

  1. 我尝试使用分离器,它确实有效,如果流的格式为“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')"/>
    

    需要你的专家观点:我做错了什么,或者什么是最好的方法。

    服务器套接字的输入将是固定长度和空格作为分隔符的数据流。每个固定长度,我需要将它们转换成一个消息,并将其发送到相关的频道。

    问候。

1 个答案:

答案 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配置中。