Java Spring IntegrationFlow实现中的ClassCastException

Java Spring IntegrationFlow实现中的ClassCastException,java,spring,spring-integration,spring-integration-dsl,Java,Spring,Spring Integration,Spring Integration Dsl,我目前有一个IntegrationFlow实现,它利用一个服务类来实现流执行的所有所需功能。像这样的 @Service public class FlowService { public Message<String> removeLineFeeds(Message<String> message) { return MessageBuilder .withPayload(StringUtils.remove(me

我目前有一个IntegrationFlow实现,它利用一个服务类来实现流执行的所有所需功能。像这样的

@Service
public class FlowService {

    public Message<String> removeLineFeeds(Message<String> message) {
        return MessageBuilder
                .withPayload(StringUtils.remove(message.getPayload(), StringUtils.LF))
                .copyHeadersIfAbsent(message.getHeaders())
                .build();
    }

}

@Configuration
@EnableIntegration
public class FlowConfiguration {

    @Autowired
    private FlowService flowService;

    @Bean
    public IntegrationFlow flow() {
        return IntegrationFlows
                .from("inputChannel")
                .transform(flowService, "removeLineFeeds")
                .get();
    }
}
@Bean
public IntegrationFlow flow() {
    return IntegrationFlows
            .from("inputChannel")
            .transform(flowService::removeLineFeeds)
            .get();
}
不幸的是,当以这种方式实现时,流在处理消息时将抛出
ClassCastException
。我已经尝试了一些目前存在于网络上的不同的解决方案,但似乎没有一个能奏效。无论使用什么IntegrationFlow方法(转换、过滤等),我都会遇到类似的问题

当前实现需要更改哪些内容,以允许在IntegrationFlow方法中使用
flowService::removeLineFeeds

编辑:根据ARTEM的回复

似乎是集成流中的一个简单转换器完成了这个任务。我当前的实现似乎是以
消息
的形式传递消息,而不是我期望的
消息
。有关更多详细信息,请参见下文Artem的完整回复

@Bean
public IntegrationFlow flow() {
    return IntegrationFlows
            .from("inputChannel")
            .convert(String.class)
            .transform(flowService::removeLineFeeds)
            .get();
}

关键是lambda必须对应于某个功能接口。 在
transform()
的情况下,它是一个
通用变压器
。实际上,您的
Message removeLineFeeds(Message Message)
满足了这样一个契约。如果您只处理有效负载,那么它会工作得很好:

public String removeLineFeeds(String message) {
    return StringUtils.remove(message.getPayload(), StringUtils.LF);
}
因为当目标实现中的所有通用信息在运行时被擦除时,我们猜不出您想要处理整个
消息
,所以框架只会向lambda传播一个有效负载。您的
字符串
无法转换为
消息
,因此出现了
类别异常

为了解决这个问题并模拟Java泛型系统,我们建议使用一个具有显式预期类型的重载方法:

/**
 * Populate the {@link MessageTransformingHandler} instance for the provided
 * {@link GenericTransformer} for the specific {@code payloadType} to convert at
 * runtime.
 * @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 BaseIntegrationFlowDefinition}.
 * @see MethodInvokingTransformer
 * @see LambdaMessageProcessor
 */
public <P, T> B transform(Class<P> payloadType, GenericTransformer<P, T> genericTransformer) {
通过这种方式,我们可以说是一个框架,我们希望得到一个完整的消息,以便我们的函数进行处理

无论如何,我更喜欢第一个变量,它只包含一个
有效负载
:框架将为您处理应答消息中的请求头


请参阅文档中的更多信息:

谢谢您的回复。我尝试了上述两种解决方案,但仍然遇到了ClassCastException。更具体地说,异常现在读取
java.lang.ClassCastException:[B不能转换为java.lang.String
。好吧,这已经是一个不同的异常,与业务相关。您需要一个
字符串
,但您的消息包含一个
字节[]
作为有效负载。您可以从该
字节[]创建一个字符串
在transformer方法中,或者使用
convert(String.class)
并注册一个
Converter
@IntegrationConverter
bean。看起来添加了.convert(String.class)就成功了。如果我使用
.transform(flowService,“removeLineFeeds”),我的假设正确吗
Spring Integration为我处理转换?试图理解我在最初的实现中如何没有遇到这个问题。这是正确的。因为通过方法名调用会在反射中着陆,我们可以尝试将传入数据转换为预期类型。使用lambda,我们只有一个直接调用,没有人能够猜到e转换的目标类型,除非您将该重载方法与
类一起使用。。。
.transform(Message.class, flowService::removeLineFeeds)