Spring Integration DSL:使用标头的变压器

时间:2019-02-26 15:58:35

标签: spring-integration

我想使用Java DSL进行Spring集成,但是我不知道如何在转换过程中使用消息头。

我以前的实现有一个这样的Transformer:

@Transformer(inputChannel = "inputChannel", outputChannel = "outputChannel")
public EventB transform(
        EventA eventA,
        @Header("a_header") String aHeader,
        @Header("other_header") String otherHeader){
    return new EventB(eventA.getSomeField(), aHeader, otherHeader);
}

现在我有以下DSL:

@Bean
public IntegrationFlow aFlow(){
    return IntegrationFlows.from(EventASink.INPUT)
        .filter("headers['operation'] == 'OPERATION_A'")
        .transform() //<-- What should I do here?
        .handle(Http.outboundGateway(uri).httpMethod(HttpMethod.POST))
        .get();
}

我查看了transform()方法的实现,发现它可以接收GenericTransformer作为参数,但它似乎仅适用于消息有效负载,并且我还需要标头。

我还看到可以使用某种反射,但是我不喜欢它,因为它不是重构安全的。

有什么建议吗?预先感谢。

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。我需要标头和有效载荷。经过大量的修补,我找到了解决方案。我使用了 .handle 而不是 .transformGenericHandler 的 handle 方法提供有效负载和标头。 在您的情况下,它看起来像:

@Bean
public IntegrationFlow aFlow(){
return IntegrationFlows.from(EventASink.INPUT)
    .filter("headers['operation'] == 'OPERATION_A'")
    .<EventA>handle((eventA, h) -> new EventB(
        eventA.getSomeField(),
        h.get("a_header", String.class),
        h.get("other_header", String.class)))
    .handle(Http.outboundGateway(uri).httpMethod(HttpMethod.POST))
    .get();
}

答案 1 :(得分:0)

由于DSL是Framework的一部分,并且在开始使用DSL之前就已经进行了编译,因此我们无法推断出任何自定义POJO方法,因此,没有像这样的简单方法可以对任何自定义标头进行计数

使用transform()合约可以在壁橱中重复使用带有参数注释的.transform()

/**
 * Populate the {@code MessageTransformingHandler} for the {@link MethodInvokingTransformer}
 * to invoke the service method at runtime.
 * @param service the service to use.
 * @param methodName the method to invoke.
 * @return the current {@link IntegrationFlowDefinition}.
 * @see MethodInvokingTransformer
 */
public B transform(Object service, String methodName)

因此,您需要使用该方法声明一个bean,并在service参数中使用它,同时在methodName参数中提及该方法。

访问标头的另一种方法是请求lambda的整个Message类型:

/**
 * Populate the {@link MessageTransformingHandler} instance for the provided
 * {@link GenericTransformer} for the specific {@code payloadType} to convert at
 * runtime.
 * Use {@link #transform(Class, GenericTransformer)} if you need access to the
 * entire message.
 * @param payloadType the {@link Class} for expected payload type. It can also be
 * {@code Message.class} if you wish to access the entire message in the transformer.
 * Conversion to this type will be attempted, if necessary.
 * @param genericTransformer the {@link GenericTransformer} to populate.
 * @param <P> the payload type - 'transform from' or {@code Message.class}.
 * @param <T> the target type - 'transform to'.
 * @return the current {@link IntegrationFlowDefinition}.
 * @see MethodInvokingTransformer
 * @see LambdaMessageProcessor
 */
public <P, T> B transform(Class<P> payloadType, GenericTransformer<P, T> genericTransformer) {

在这种情况下,代码可能是这样的:

  .transform(Message.class, m -> m.getHeaders())