OSB 12.2.1.0.0项目:SFTP业务服务如何动态切换目标文件夹?
针对你在JDeveloper里基于12.2.1.0.0版本Service Bus项目遇到的SFTP动态目录路由问题(按文件扩展名分发到directory1/directory2,且无法使用WebLogic FTP适配器),我给你两个实用的解决方案:
方法一:利用动态URI配置业务服务
这是最直接的原生方案,不需要额外组件,完全基于OSB的传输特性:
配置SFTP业务服务的基础URI
先创建你的SFTP业务服务,在传输配置的URI里使用占位符,比如:sftp://[username]:[password]@[sftp-server]:[port]/${targetDir}这里的
${targetDir}是后续要动态替换的变量,记得把实际的用户名、密码、服务器地址、端口替换成你的真实信息。在代理服务流水线中提取文件扩展名
在代理服务的流水线里,先从入站传输头中获取文件名(OSB会自动把文件名放到传输头里),用XPath表达式提取扩展名:fn:substring-after($inbound/ctx:transport/ctx:request/ctx:headers/ctx:fileName, '.')可以把这个结果存到一个流水线变量里,比如
$ext。根据扩展名设置目标目录变量
添加一个Assign活动,用条件逻辑设置targetDir变量:- 如果
$ext等于txt(或者你需要的扩展名),就把targetDir设为directory1 - 如果是其他扩展名(比如
csv),设为directory2
示例Assign的表达式:
if ($ext = 'txt') then 'directory1' else 'directory2'- 如果
在Invoke活动中动态替换URI
在调用SFTP业务服务的Invoke活动里,找到URI属性,选择“Expression”模式,引用我们的targetDir变量,最终的URI表达式类似:concat('sftp://[username]:[password]@[sftp-server]:[port]/', $targetDir)这样每次调用业务服务时,URI会自动替换成对应的目标目录。
方法二:使用Java Callout实现复杂逻辑(可选)
如果你的扩展名判断逻辑比较复杂(比如多个扩展名对应同一个目录),可以用Java Callout来封装逻辑:
编写Java类
写一个简单的Java类,提供静态方法接收文件名,返回目标目录:public class SftpDirectoryRouter { public static String getTargetDirectory(String fileName) { if (fileName == null || !fileName.contains(".")) { return "directory2"; // 默认目录 } String ext = fileName.substring(fileName.lastIndexOf(".") + 1); switch(ext.toLowerCase()) { case "txt": case "log": return "directory1"; case "csv": case "xml": return "directory2"; default: return "directory2"; } } }在OSB项目中引入Java类
把编译好的JAR包添加到Service Bus项目的库中,或者直接在项目里创建Java源文件(JDeveloper支持在SB项目里添加Java资源)。在流水线中调用Java Callout
添加一个Java Callout活动,调用上面的静态方法,传入文件名变量,把返回结果存到targetDir变量里,然后再按照方法一的步骤,在Invoke活动中动态设置URI。
注意事项
- 确保SFTP服务器上的directory1和directory2已经存在,且业务服务使用的SFTP用户有写入权限
- 测试时可以用OSB的测试控制台,模拟不同扩展名的文件,检查是否正确路由到对应目录
- 如果需要保留原文件名,确保在传输头里传递
fileName,避免文件被重命名
内容的提问来源于stack exchange,提问作者Alone89

