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

Spring Integration中SftpOutboundGateway执行GET时抛SpelEvaluationException

问题根因
  • 核心错误出在localFilenameExpression、remoteDirectoryExpression两个方法的使用上:这两个方法的入参要求是SpEL表达式字符串,而非直接的配置值字符串。Spring会把你传入的目录、文件名字面值当成表达式执行,默认执行上下文的根对象是当前消息,因此会抛出GenericMessage无法转换为String的类型转换异常。
  • 次要问题:SFTP Outbound Gateway执行GET命令后返回的payload是java.io.File类型,你直接调用fromJson转换器会解析失败,需要先把文件内容读取为字符串再做JSON转换。
修正方案

方案1:使用固定值配置(不需要动态从消息取参数)

直接使用非Expression后缀的方法传入固定配置值即可,修正后的IntegrationFlow配置如下:

@Bean
public IntegrationFlow sftpGetFlow(TransferContext context) {
    return IntegrationFlows.from("sftpGetInputChannel")
            .handle(Sftp.outboundGateway(sftpSessionFactory(context.getChannel()),
                            AbstractRemoteFileOutboundGateway.Command.GET, "payload")
                    // 用remoteDirectory传固定目录,不要用Expression版本
                    .remoteDirectory(context.getRemoteDir())
                    .localDirectory(new File(context.getLocalDir()))
                    // 用localFilename传固定文件名,不要用Expression版本
                    .localFilename(context.getLocalFilename())
            )
            // 先读取文件内容为字符串
            .transform(Files.toStringTransformer())
            // 再转换为Event数组
            .transform(Transformers.fromJson(Event[].class))
            .channel("remoteFileOutputChannel")
            .get();
}

方案2:需要动态从消息获取参数的场景

如果你需要根据请求消息的内容动态指定目录、文件名,就编写正确的SpEL表达式传入Expression后缀的方法即可,示例如下:

// 从消息头获取远程目录
.remoteDirectoryExpression("headers.remoteDir")
// 从消息payload获取本地文件名
.localFilenameExpression("payload.localFileName")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 04:48:02