java - Spring 集成版本 3.0 : Splitting TCP stream message into multiple Messages based on content

标签 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" />

下面的部分是空的,因为我不确定在这里要实现什么,以便它可以调用我的路由器,而路由器将完成它的业务。


我已经尝试使用拆分器,它确实有效,如果流以“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;
}

下面是我的路由器,它会根据一些表达式发送到相应的 channel :

<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')"/>

需要您对此的专家意见:关于我做错了什么,或者什么是最好的方法。

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

问候。

最佳答案

首先没理由自己实现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配置。

关于java - Spring 集成版本 3.0 : Splitting TCP stream message into multiple Messages based on content,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32167433/

相关文章:

java - 带破折号的POST参数的Struts2 setter方法

java - CORS和错误以及Access-Control-Allow-Origin header 的问题

c++ - 在 Node.js 中使用 native 代码的最佳方式是什么?

Android 6.0 无法创建套接字

java - API每次响应不同的JSON类型

Java 游戏编程库

java - Collections.synchronizedList() 使用什么模式

Spring 3.1 MVC框架 session 管理

java - MyBatis 将属性映射到错误的 Enum

c++ - 通过 TCP 套接字发送大的 Base64 字符串