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

基于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:50:23