Camel文件路由异常时文件误移至Completed目录问题排查
Camel文件路由异常时文件仍被移至Completed目录的问题解决
问题根源
你当前的路由配置里,move=Completed是Camel文件组件的默认后置操作——不管路由内的处理是否抛出异常,文件组件都会在消费完文件后执行这个移动动作,这就是为什么即使ActualProcessor抛出异常,文件还是会被移去Completed目录。你写的doCatch块只是把消息转发到另一个file组件,但这根本阻止不了原文件组件的自动move逻辑。
解决方案
推荐两种可行的处理方式,按需选择:
方案1:利用文件组件原生的moveFailed参数(推荐)
直接在原文件组件URI里添加moveFailed=Reprocess,组件会自动处理成功/异常的分支:处理成功时文件从InProcess移到Completed,异常时移到Reprocess。同时可以删掉原来的doTry/doCatch块,简化代码。
修改后的代码:
from("file:src/path?preMove=InProcess&move=Completed&moveFailed=Reprocess&delete=false&idempotent=false&idempotentKey=${file:name}-${file:size}&readLock=rename&readLockMinAge=10s&renameUsingCopy=true&filterFile=$simple{file:size} > 0 &include=.*.xml") .convertBodyTo(String.class) .routeId("test-route") .bean(ActualProcessor.class, "process");
方案2:手动控制文件移动(适合复杂场景)
禁用文件组件的自动move功能(把move参数设为空或move=.),然后在路由的成功分支手动将文件移到Completed,异常分支移到Reprocess,最后删除InProcess里的原文件。
代码示例:
from("file:src/path?preMove=InProcess&move=&delete=false&idempotent=false&idempotentKey=${file:name}-${file:size}&readLock=rename&readLockMinAge=10s&renameUsingCopy=true&filterFile=$simple{file:size} > 0 &include=.*.xml") .convertBodyTo(String.class) .routeId("test-route") .doTry() .bean(ActualProcessor.class, "process") // 处理成功:移到Completed目录 .to("file:src/path/Completed?fileName=${file:name}") // 删除InProcess中的原文件 .to("file:src/path/InProcess?operation=delete&fileName=${file:name}") .doCatch(Throwable.class) // 异常时:移到Reprocess目录 .to("file:src/path/Reprocess?fileName=${file:name}") .to("file:src/path/InProcess?operation=delete&fileName=${file:name}") .end();
方案对比
- 方案1简洁高效,完全利用Camel的原生能力,维护成本低,优先推荐。
- 方案2灵活性更高,适合需要在文件移动前后执行额外业务逻辑的场景,但代码相对繁琐。
内容的提问来源于stack exchange,提问作者MR_K
相关产品推荐
相关产品推荐

