基于Camel DSL与Spring,从单处理器向SFTP多文件夹传多文件
在Apache Camel中实现额外SFTP文件传输的方案
看起来你已经在Processor里拿到了额外文件的路径和内容,现在需要把这个文件也传到SFTP服务器对吧?这里有几个实用的方案,你可以根据自己的场景选择:
方案一:使用ProducerTemplate在Processor内直接发送
这是最直接的方式,不需要修改原有路由结构,在Processor里独立发送额外文件,不影响主文件的传输流程:
首先在路由类中注入ProducerTemplate,然后在Processor里构建SFTP地址并发送:
@Component public class UploadRoutesDefinition extends RouteBuilder { @Autowired private ProducerTemplate producerTemplate; @Autowired private SystemSettingsService systemSettingsService; private static final String SFTP_BASE_URL = "sftp://%s@%s:%s/%s?password=%s"; @Override public void configure() throws Exception { from("seda:rest_upload") .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { // 原有处理主文件的逻辑... String sftpErrorFileTextPath = "..."; // 你拿到的额外文件路径 String pushErrorMessage = exchange.getProperty(PUSH_ERROR_MESSAGE, String.class); // 构建额外文件的SFTP地址,加上你需要的append参数 String additionalSftpUrl = String.format(SFTP_BASE_URL + "&fileExist=Append", systemSettingsService.getSystemSettings().getSftpUserName(), systemSettingsService.getSystemSettings().getSftpHost(), systemSettingsService.getSystemSettings().getSftpPort(), sftpErrorFileTextPath, systemSettingsService.getSystemSettings().getSftpPassword()); // 发送额外文件:设置文件名和内容 producerTemplate.sendBodyAndHeaders(additionalSftpUrl, pushErrorMessage.getBytes(), Map.of("CamelFilename", "ololo.txt")); } }) // 原有主文件的SFTP传输逻辑 .to(String.format(SFTP_BASE_URL + "&fileExist=Append", systemSettingsService.getSystemSettings().getSftpUserName(), systemSettingsService.getSystemSettings().getSftpHost(), systemSettingsService.getSystemSettings().getSftpPort(), systemSettingsService.getSystemSettings().getSftpAttachmentsPushFailedPath(), systemSettingsService.getSystemSettings().getSftpPassword())); } }
这种方式适合不需要保证主文件和额外文件传输原子性的场景,额外文件的发送是独立异步的。
方案二:使用Multicast组件同步/并行传输两个文件
如果你希望主文件和额外文件的传输是同步或并行执行的,可以用Multicast拆分路由分支:
@Override public void configure() throws Exception { from("seda:rest_upload") .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { // 原有处理逻辑 String sftpErrorFileTextPath = "..."; String pushErrorMessage = exchange.getProperty(PUSH_ERROR_MESSAGE, String.class); // 将额外文件信息存入Exchange属性,供后续分支使用 exchange.setProperty("additionalFilePath", sftpErrorFileTextPath); exchange.setProperty("additionalContent", pushErrorMessage.getBytes()); } }) // 多播到两个独立路由,parallelProcessing可选,开启后并行处理 .multicast().parallelProcessing() .to("direct:transferMainFile") .to("direct:transferAdditionalFile"); // 主文件传输分支 from("direct:transferMainFile") .to(String.format(SFTP_BASE_URL + "&fileExist=Append", systemSettingsService.getSystemSettings().getSftpUserName(), systemSettingsService.getSystemSettings().getSftpHost(), systemSettingsService.getSystemSettings().getSftpPort(), systemSettingsService.getSystemSettings().getSftpAttachmentsPushFailedPath(), systemSettingsService.getSystemSettings().getSftpPassword())); // 额外文件传输分支 from("direct:transferAdditionalFile") .process(exchange -> { String filePath = exchange.getProperty("additionalFilePath", String.class); byte[] content = exchange.getProperty("additionalContent", byte[].class); String sftpUrl = String.format(SFTP_BASE_URL + "&fileExist=Append", systemSettingsService.getSystemSettings().getSftpUserName(), systemSettingsService.getSystemSettings().getSftpHost(), systemSettingsService.getSystemSettings().getSftpPort(), filePath, systemSettingsService.getSystemSettings().getSftpPassword()); exchange.getIn().setBody(content); exchange.getIn().setHeader("CamelFilename", "ololo.txt"); }) .toD("${in.header.sftpUrl}"); // 使用toD支持动态URL解析 }
Multicast会复制原Exchange到每个分支,适合需要统一管控两个文件传输状态的场景。
注意点
- 如果你需要动态解析URL(比如用header里的路径),一定要用
toD而不是to,to只支持静态地址,toD才会解析表达式。 fileExist=Append参数是Camel SFTP组件的配置,用来指定文件已存在时的行为,可选值还有Override(覆盖)、Fail(报错)等,根据你的需求调整即可。
内容的提问来源于stack exchange,提问作者gstackoverflow
相关产品推荐
相关产品推荐

