如何正确使用SftpOutboundGateway的MPUT命令上传文件夹文件?
问题排查与解决
一、初始问题:仅上传单个文件+远程文件名变为消息ID.msg
问题原因
- 文件名异常:SftpOutboundGateway默认若未指定
remoteFileName表达式,会将消息ID作为远程文件名并添加.msg后缀,这是因为默认逻辑将消息payload当作文件内容处理,而非文件路径/对象。 - 仅传单个文件:大概率是消息payload仅包含单个文件(或文件夹未配置过滤器),或未正确触发MPUT的批量处理逻辑。
解决步骤
- 配置远程文件名映射:在SftpOutboundGateway中通过
remoteFileName表达式指定使用本地文件名,确保远程文件名与本地一致:
.handle(Sftp.outboundGateway(sftpSessionFactory, Command.MPUT, "payload") .remoteDirectory("/your/remote/target/dir") .remoteFileName("#{payload.getName()}") // 若payload是File对象,直接引用名称 // 若payload是文件夹路径,改用:.remoteFileName("#{file.getName()}") ...)
- 确保批量文件被正确识别:
- 若传入文件夹路径,需配置文件过滤器匹配目标文件:
.filter(new SimplePatternFileListFilter("foo*.TEST.txt")) - 若直接传入文件集合,确保消息payload是
File[]或List<File>类型,示例发送逻辑:File exportDir = new File("~/sftp-outbound/Export"); File[] targetFiles = exportDir.listFiles(f -> f.getName().matches("foo.*\\.TEST\\.txt")); messagingGateway.uploadFiles(targetFiles);
- 若传入文件夹路径,需配置文件过滤器匹配目标文件:
- 验证MPUT命令配置:无需额外
-R递归选项,确保命令参数"payload"正确指向文件/文件夹路径或文件集合。
二、修改配置后出现的SpEL异常:找不到'data'属性
问题原因
移除RemoteFileTemplate并将网关参数改为java.io.File后,消息payload直接是File对象,但原有配置中仍有SpEL表达式引用了data属性(通常data是消息包装类的属性,比如旧配置用#{data.payload}),而File对象本身没有data属性,导致表达式解析失败。
解决步骤
- 检查并修正所有SpEL表达式:将所有引用
data的表达式改为直接引用payload,例如:- 错误写法:
#{data.payload.getName()} - 正确写法:
#{payload.getName()}
- 错误写法:
- 验证网关接口参数绑定:确保网关接口方法接收正确的参数类型,示例:
@Gateway(requestChannel = "sftpMputInputChannel") void uploadFiles(File[] targetFiles); - 排查Subflow中的表达式:若使用Subflow风格,检查子流程中是否有处理器错误引用了
data属性,统一替换为payload即可。
内容的提问来源于stack exchange,提问作者JBStonehenge
相关产品推荐
相关产品推荐

