使用Header Enricher / SpEL解析连接ID并在Map中查找

时间:2019-03-27 14:30:15

标签: spring-integration

我有一个ConcurrentHashMap,它将服务器连接映射到客户端 连接:

{localhost:6080:50848:42a5d558-6264-4f2f-83c4-5a9964e1d168=localhost:50847:6060:a7da2280-abe3-4fce-9650-4e8a0ae31891}

我需要使用Header Enricher拦截传入的消息,解析其消息 当前的ip_connectionId标头,在我的地图中查找该键,然后使用值更新ip_connectionId

    @Bean
    @Transformer(inputChannel="responseChannel1", outputChannel="responseChannel2")
    public HeaderEnricher responseEnricher() {

        Map<String, HeaderValueMessageProcessor<?>> headersToAdd = new HashMap<>();

        Expression expression = new SpelExpressionParser().parseExpression("headers['ip_connectionId']");

        try {
            String serverConnectionId = expression.getValue(String.class);
            log.info(serverConnectionId);

            String clientConnectionId = outboundToInboundMap.get(serverConnectionId);
            log.info(clientConnectionId);

            headersToAdd.put("ip_connectionId", new StaticHeaderValueMessageProcessor<>(clientConnectionId));
        } catch (Exception e) {
            e.printStackTrace();
        }

        HeaderEnricher enricher = new HeaderEnricher(headersToAdd);
        enricher.setDefaultOverwrite(true);
        return enricher;
    }

运行此命令时,看不到日志语句,仍然出现此错误:

org.springframework.messaging.MessageHandlingException: Unable to find outbound socket

因为ip_connectionId标头未更改。

我想念什么?谢谢

1 个答案:

答案 0 :(得分:0)

您声明一个@Bean,并在bean定义阶段尝试对outboundToInboundMap进行活动的运行时操作。这是事实,outboundToInboundMap.get()在这里做为时过早,您在该地图中还没有任何内容。

您需要做的实际上是在运行时执行responseChannel1发送操作的逻辑。为此,您不能使用StaticHeaderValueMessageProcessor。您只需要一个ExpressionEvaluatingHeaderValueMessageProcessor

@Bean
@Transformer(inputChannel="responseChannel1", outputChannel="responseChannel2")
public HeaderEnricher responseEnricher() {

    Map<String, HeaderValueMessageProcessor<?>> headersToAdd = new HashMap<>();

    headersToAdd.put("ip_connectionId", 
       new ExpressionEvaluatingHeaderValueMessageProcessor<>("@outboundToInboundMap[headers['ip_connectionId']]", String .class));

    HeaderEnricher enricher = new HeaderEnricher(headersToAdd);
    enricher.setDefaultOverwrite(true);
    return enricher;
}

这样,将在运行时根据请求消息对表达式进行求值,您需要将outboundToInboundMap作为具有适当名称的bean。我使用了outboundToInboundMap,但是您可以将该bean引用更改为地图的真实bean名称。