关于SFTP Outbound Gateway使用Rotating Server Advice的技术咨询
问题1:用Rotating Server Advice配合SFTP Outbound Gateway实现跨服务器/目录的文件重命名
核心思路
RotatingServerAdvice的本质是拦截消息处理流程,轮换使用配置的SFTP会话工厂(对应不同服务器/目录)。只需将该Advice添加到SFTP Outbound Gateway的通知链中,即可让重命名操作跟随轮转逻辑执行。
具体配置步骤
配置多SFTP会话工厂
为每台目标服务器/目录创建独立的SftpSessionFactory,存入列表统一管理:@Bean public List<SftpSessionFactory> sftpSessionFactories() { List<SftpSessionFactory> factories = new ArrayList<>(); // 服务器1的会话工厂 DefaultSftpSessionFactory factory1 = new DefaultSftpSessionFactory(); factory1.setHost("server1.example.com"); factory1.setPort(22); factory1.setUser("user1"); factory1.setPassword("pass1"); factory1.setRemoteDirectory("/path/to/dir1"); factories.add(factory1); // 服务器2的会话工厂 DefaultSftpSessionFactory factory2 = new DefaultSftpSessionFactory(); factory2.setHost("server2.example.com"); factory2.setPort(22); factory2.setUser("user2"); factory2.setPassword("pass2"); factory2.setRemoteDirectory("/path/to/dir2"); factories.add(factory2); return factories; }配置Server列表轮转器
使用FixedIntervalServerListRotator(或自定义轮转逻辑)管理会话工厂的轮换顺序:@Bean public ServerListRotator serverListRotator() { return new FixedIntervalServerListRotator(sftpSessionFactories()); }配置Rotating Server Advice
创建Advice实例并绑定轮转器:@Bean public RotatingServerAdvice rotatingServerAdvice() { return new RotatingServerAdvice(serverListRotator()); }配置SFTP Outbound Gateway并绑定Advice
定义执行重命名的网关,将Advice加入其通知链,同时通过表达式确保重命名路径与当前轮转的服务器/目录匹配:@Bean @ServiceActivator(inputChannel = "sftpRenameChannel") public MessageHandler sftpOutboundGateway() { SftpOutboundGateway gateway = new SftpOutboundGateway(sftpSessionFactories().get(0), "rename", "'#{remoteDirectory}/' + headers.sourceFilename", "'#{remoteDirectory}/processed/' + headers.sourceFilename + '.done'"); gateway.setAdviceChain(Collections.singletonList(rotatingServerAdvice())); return gateway; }remoteDirectory会自动引用当前轮转会话工厂配置的远程目录- 通过消息头(如
sourceFilename)传递要重命名的文件名,确保操作针对性
关键注意点
- 若需灵活轮转目录(而非绑定到会话工厂),可自定义
ServerListRotator,轮换时更新目录变量,再通过remote-directory-expression引用该变量
问题2:用SFTP Outbound Gateway的list命令实现多服务器/目录的文件名+路径枚举
核心思路
复用RotatingServerAdvice实现会话工厂轮换,再对ls命令的返回结果做转换,仅保留文件名和路径信息。
具体配置步骤
复用已有配置
直接使用问题1中定义的rotatingServerAdvice()、sftpSessionFactories()等Bean,无需重复配置。配置执行list命令的SFTP Outbound Gateway
@Bean @ServiceActivator(inputChannel = "sftpListChannel", outputChannel = "sftpListResultChannel") public MessageHandler sftpListGateway() { SftpOutboundGateway gateway = new SftpOutboundGateway(sftpSessionFactories().get(0), "ls", "'#{remoteDirectory}'"); gateway.setAdviceChain(Collections.singletonList(rotatingServerAdvice())); return gateway; }添加结果转换逻辑
在输出通道后添加转换器,将LsEntry对象转换为包含文件名和路径的字符串:@Bean @Transformer(inputChannel = "sftpListResultChannel", outputChannel = "finalListOutputChannel") public Object transformLsEntries(List<LsEntry> entries) { return entries.stream() .map(entry -> entry.getFilename() + " | " + entry.getRemoteDirectory()) .collect(Collectors.toList()); }
关键注意点
- 若需轮转同一服务器下的多个目录,可修改
ServerListRotator,轮换时更新remoteDirectory变量,再通过remote-directory-expression引用 - 仅需列出文件时,可在网关中添加过滤器:
gateway.setFilter(new AcceptAllFileListFilter<LsEntry>() { @Override public boolean accept(LsEntry entry) { return !entry.isDirectory(); } });
内容的提问来源于stack exchange,提问作者Harpreet Saund
相关产品推荐
相关产品推荐

