Spring integration 如何在Spring Integration DSL Tcp中使用消息头进行路由

Spring integration 如何在Spring Integration DSL Tcp中使用消息头进行路由,spring-integration,spring-integration-dsl,spring-integration-ip,Spring Integration,Spring Integration Dsl,Spring Integration Ip,我有两个服务器端服务,我希望使用消息头将消息路由到它们,远程客户端将服务标识放入字段type 来自服务器端配置的代码段是否正确?它抛出强制转换异常,指示route()只查看有效负载,而不查看消息头。此外,Spring集成手册中的所有示例仅显示基于有效载荷的决策 @Bean public IntegrationFlow serverFlow( // common flow for all my services, currently 2 TcpNetServerConnection

我有两个服务器端服务,我希望使用消息头将消息路由到它们,远程客户端将服务标识放入字段
type

来自服务器端配置的代码段是否正确?它抛出强制转换异常,指示
route()
只查看有效负载,而不查看消息头。此外,Spring集成手册中的所有示例仅显示基于有效载荷的决策

@Bean
public IntegrationFlow serverFlow( // common flow for all my services, currently 2
        TcpNetServerConnectionFactory serverConnectionFactory,
        HeartbeatServer heartbeatServer,
        FeedServer feedServer) {
    return IntegrationFlows
            .from(Tcp.inboundGateway(serverConnectionFactory))
            .<Message<?>, String>route((m) -> m.getHeaders().get("type", String.class),
                (routeSpec) -> routeSpec
                .subFlowMapping("hearbeat", subflow -> subflow.handle(heartbeatServer::processRequest))
                .subFlowMapping("feed", subflow -> subflow.handle(feedServer::consumeFeed)))
            .get();
}

和往常一样,这里是完整的演示,并且。

没有通过原始TCP发送头的标准方法。您需要以某种方式将它们编码到有效负载中(并在服务器端提取它们)

框架提供了一种机制来为您实现这一点,但它需要额外的配置

具体地说

MapJsonSerializer
使用Jackson对象映射器在映射和JSON之间进行转换。您可以将此序列化程序与
messageconvertingcpmessageapper
MapMessageConverter
结合使用,以JSON格式传输选定的头和负载

我将试着找些时间创建一个如何使用它的示例

但是,当然,您可以自己进行编码/解码

编辑

下面是一个使用JSON通过TCP传输消息头的配置示例

@SpringBootApplication
public class TcpWithHeadersApplication {

    public static void main(String[] args) {
        SpringApplication.run(TcpWithHeadersApplication.class, args);
    }

    // Client side

    public interface TcpExchanger {

        public String exchange(String data, @Header("type") String type);

    }

    @Bean
    public IntegrationFlow client(@Value("${tcp.port:1234}") int port) {
        return IntegrationFlows.from(TcpExchanger.class)
                .handle(Tcp.outboundGateway(Tcp.netClient("localhost", port)
                        .deserializer(jsonMapping())
                        .serializer(jsonMapping())
                        .mapper(mapper())))
                .get();
    }

    // Server side

    @Bean
    public IntegrationFlow server(@Value("${tcp.port:1234}") int port) {
        return IntegrationFlows.from(Tcp.inboundGateway(Tcp.netServer(port)
                        .deserializer(jsonMapping())
                        .serializer(jsonMapping())
                        .mapper(mapper())))
                .log(Level.INFO, "exampleLogger", "'Received type header:' + headers['type']")
                .route("headers['type']", r -> r
                        .subFlowMapping("upper",
                                subFlow -> subFlow.transform(String.class, p -> p.toUpperCase()))
                        .subFlowMapping("lower",
                                subFlow -> subFlow.transform(String.class, p -> p.toLowerCase())))
                .get();
    }

    // Common

    @Bean
    public MessageConvertingTcpMessageMapper mapper() {
        MapMessageConverter converter = new MapMessageConverter();
        converter.setHeaderNames("type");
        return new MessageConvertingTcpMessageMapper(converter);
    }

    @Bean
    public MapJsonSerializer jsonMapping() {
        return new MapJsonSerializer();
    }

    // Console

    @Bean
    @DependsOn("client")
    public ApplicationRunner runner(TcpExchanger exchanger,
            ConfigurableApplicationContext context) {

        return args -> {
            System.out.println("Enter some text; if it starts with a lower case character,\n"
                    + "it will be uppercased by the server; otherwise it will be lowercased;\n"
                    + "enter 'quit' to end");
            Scanner scanner = new Scanner(System.in);
            String request = scanner.nextLine();
            while (!"quit".equals(request.toLowerCase())) {
                if (StringUtils.hasText(request)) {
                    String result = exchanger.exchange(request,
                            Character.isLowerCase(request.charAt(0)) ? "upper" : "lower");
                    System.out.println(result);
                }
                request = scanner.nextLine();
            }
            scanner.close();
            context.close();
        };
    }

}

是的,我怀疑无法发送头,很高兴得到确认。我添加了一个如何使用JSON发送头的示例。
@SpringBootApplication
public class TcpWithHeadersApplication {

    public static void main(String[] args) {
        SpringApplication.run(TcpWithHeadersApplication.class, args);
    }

    // Client side

    public interface TcpExchanger {

        public String exchange(String data, @Header("type") String type);

    }

    @Bean
    public IntegrationFlow client(@Value("${tcp.port:1234}") int port) {
        return IntegrationFlows.from(TcpExchanger.class)
                .handle(Tcp.outboundGateway(Tcp.netClient("localhost", port)
                        .deserializer(jsonMapping())
                        .serializer(jsonMapping())
                        .mapper(mapper())))
                .get();
    }

    // Server side

    @Bean
    public IntegrationFlow server(@Value("${tcp.port:1234}") int port) {
        return IntegrationFlows.from(Tcp.inboundGateway(Tcp.netServer(port)
                        .deserializer(jsonMapping())
                        .serializer(jsonMapping())
                        .mapper(mapper())))
                .log(Level.INFO, "exampleLogger", "'Received type header:' + headers['type']")
                .route("headers['type']", r -> r
                        .subFlowMapping("upper",
                                subFlow -> subFlow.transform(String.class, p -> p.toUpperCase()))
                        .subFlowMapping("lower",
                                subFlow -> subFlow.transform(String.class, p -> p.toLowerCase())))
                .get();
    }

    // Common

    @Bean
    public MessageConvertingTcpMessageMapper mapper() {
        MapMessageConverter converter = new MapMessageConverter();
        converter.setHeaderNames("type");
        return new MessageConvertingTcpMessageMapper(converter);
    }

    @Bean
    public MapJsonSerializer jsonMapping() {
        return new MapJsonSerializer();
    }

    // Console

    @Bean
    @DependsOn("client")
    public ApplicationRunner runner(TcpExchanger exchanger,
            ConfigurableApplicationContext context) {

        return args -> {
            System.out.println("Enter some text; if it starts with a lower case character,\n"
                    + "it will be uppercased by the server; otherwise it will be lowercased;\n"
                    + "enter 'quit' to end");
            Scanner scanner = new Scanner(System.in);
            String request = scanner.nextLine();
            while (!"quit".equals(request.toLowerCase())) {
                if (StringUtils.hasText(request)) {
                    String result = exchanger.exchange(request,
                            Character.isLowerCase(request.charAt(0)) ? "upper" : "lower");
                    System.out.println(result);
                }
                request = scanner.nextLine();
            }
            scanner.close();
            context.close();
        };
    }

}