You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Integration TCP反序列化器无法获取完整消息求助

解决Spring Integration TCP接收HL7消息被拆分的问题

问题场景

我们用Spring Integration Flow对接TCP端口接收HL7消息,当前代码如下:

@Bean
public IntegrationFlow integrationFlow() {
    return IntegrationFlows.from(Tcp.inboundGateway(Tcp.nioServer(port)
            //.deserializer(new HL7Deserializer())
            .deserializer(TcpCodecs.lengthHeader1())
           .serializer(TcpCodecs.lengthHeader1())
            ))
            .transform(Transformers.objectToString())
            .channel("testChannel")
        .get();
}


@Bean
public IntegrationFlow testingChannnel() {
    return IntegrationFlows.from("testChannel")
            .handle("messageHandler", "handleMessage")
        .get();
}

@Component
public class MessageHandle implements MessageHandler {

    @Override
    public void handleMessage(Message<?> message) {
        String payload = message.getPayload().toString();
        System.out.println("Received message: " + payload);
    }
}

输入的HL7格式消息:

MSH~|&HTAPPL200TSQA~SQA-VENDOR~DNSDG HOME TELEHEALTH613~SQA-VA~DNS20170530223011^ACK~A04200 TSQAApplication320170530223011T2.4^^ALNEUSA
MSAAA613Application120170530223005^^^^0~Message accepted^

现在遇到的问题是:反序列化时消息被拆分接收,收到的内容如下:

Received message: MSH~|&HT
Received message: PPL200TSQA~SQA-VENDOR~DNSDG HOME TELEHEALTH613~SQA-VA~DNS2017
Received message: 530223011^ACK~A04200 TSQAApplication3201705302
Received message: 3011T2.4^^ALNEUSA
MSAAA613Application12017

问题原因

你当前用的TcpCodecs.lengthHeader1()是基于1字节长度头的编解码器,它要求消息开头必须带1个字节的长度标识,用来告诉解码器后续要读取多少字节的内容。但HL7消息本身并不遵循这个规则,HL7是靠特定的结束符(通常是\r)或者自身的结构来标识完整消息的,所以用长度头解码器会把HL7消息按错误的规则拆成碎块。

修改方案

方案1:启用HL7专用编解码器(推荐)

你代码里已经注释了HL7Deserializer,这是Spring Integration专门为HL7消息设计的反序列化器,直接启用它就行,同时配套使用HL7序列化器处理响应:

@Bean
public IntegrationFlow integrationFlow() {
    return IntegrationFlows.from(Tcp.inboundGateway(Tcp.nioServer(port)
            .deserializer(new HL7Deserializer())
            .serializer(new HL7Serializer()) // 发送HL7响应时用专用序列化器
            ))
            .transform(Transformers.objectToString())
            .channel("testChannel")
        .get();
}

提示:HL7Deserializer默认用\r作为消息结束符,如果你对接的系统用的是其他结束符(比如\n),可以通过构造方法指定,例如new HL7Deserializer('\n')。

方案2:使用基于结束符的通用编解码器

如果不想用HL7专用的,也可以用Spring Integration提供的基于结束符的编解码器,指定HL7消息的结束符即可:

@Bean
public IntegrationFlow integrationFlow() {
    return IntegrationFlows.from(Tcp.inboundGateway(Tcp.nioServer(port)
            .deserializer(TcpCodecs.cr()) // 以\r作为结束符,对应HL7标准
            .serializer(TcpCodecs.cr())
            ))
            .transform(Transformers.objectToString())
            .channel("testChannel")
        .get();
}

注意:这种方式只是简单按结束符分割消息,不如HL7专用解码器适配性强,无法处理HL7消息的一些特殊结构场景。

验证效果

修改完成后重启服务,再发送完整的HL7消息,就能收到完整的内容,不会再出现拆分的情况。

内容的提问来源于stack exchange,提问作者Piratheepan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 13:34:52