能否动态修改Spring SFTP入站通道适配器的filename-regex?
你的场景是用户在UI选择文件后触发下载,多用户可并发操作且仅文件名不同,而<int-sftp:inbound-channel-adapter>是静态轮询式的拉取组件,它的filename-regex是预配置的静态值,确实没法满足动态指定下载文件的需求。咱们可以用SFTP Outbound Gateway来实现这个功能,它能接收动态请求参数,按需触发指定文件的下载。
为什么Inbound Channel Adapter不适合?
<int-sftp:inbound-channel-adapter>是为主动轮询拉取远程目录文件设计的,配置是静态的,运行时无法修改filename-regex;而且它的触发逻辑是基于poller的定时任务,不是响应用户的点击请求,完全匹配不上你“用户触发、动态指定文件”的场景。
具体修改步骤
1. 替换配置为SFTP Outbound Gateway
把原来的inbound-adapter配置替换为outbound-gateway,同时定义一个网关接口作为业务代码的入口:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration" xmlns:int-sftp="http://www.springframework.org/schema/integration/sftp" xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration/sftp http://www.springframework.org/schema/integration/sftp/spring-integration-sftp.xsd"> <import resource="SftpSampleCommon.xml"/> <!-- 包含你的sftpSessionFactory等公共配置 --> <!-- 定义网关接口,作为业务代码调用Spring Integration流程的入口 --> <int:gateway id="gw" service-interface="com.rizwan.test.sftp_outbound_gateway.ToSftpFlowGateway" default-request-channel="toGet"/> <!-- SFTP Outbound Gateway,执行get命令下载指定文件 --> <int-sftp:outbound-gateway id="gatewayGET" local-directory="C:\Users\503017993\Perforce\rizwan.shaikh1_G7LGTPC2E_7419\NGI\DEV\Jetstream_Branches\C360_Falcon2_1_Main\sftp-outbound-gateway" session-factory="sftpSessionFactory" request-channel="toGet" remote-directory="/si.sftp.sample" command="get" command-options="-P" expression="payload"> <!-- 可选:配置重试增强,处理SFTP网络异常 --> <int-sftp:request-handler-advice-chain> <int:retry-advice /> </int-sftp:request-handler-advice-chain> </int-sftp:outbound-gateway> </beans>
关键配置说明:
command="get":指定执行下载文件的命令expression="payload":用请求消息的payload(也就是你传入的文件名)作为要下载的远程文件路径command-options="-P":保留远程文件的修改时间,属于可选参数- 网关接口
ToSftpFlowGateway需要你自行定义,比如包含String downloadRemoteFile(String remoteFilePath);方法
2. 修改业务触发代码
原来的轮询启动adapter的代码可以替换为调用网关接口,传入用户选择的文件名即可触发下载:
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/META-INF/spring-context.xml"); // 获取网关Bean DownloadRemoteFileGateway downloadGateway = ctx.getBean(DownloadRemoteFileGateway.class); // 传入用户选择的远程文件名/相对路径,触发下载 String downloadedFilePath = downloadGateway.downloadRemoteFile("si.sftp.sample/2ftptest");
3. 并发支持
因为你的场景是多用户同时下载,之前配置的CachingSessionFactory已经支持多会话缓存,配合Spring Integration的线程安全通道,完全可以处理并发请求——每个请求会使用独立的SFTP会话(或者从缓存中获取空闲会话)。
原配置问题回顾
你原来的<int-sftp:inbound-channel-adapter>配置中:
<int-sftp:inbound-channel-adapter id="sftpInbondAdapter" auto-startup="false" channel="receiveChannel" session-factory="sftpSessionFactory" local-directory="file:local-dir" remote-directory="si.sftp.sample" auto-create-local-directory="true" delete-remote-files="false" filename-regex="a.txt"> <int:poller fixed-rate="0" max-messages-per-poll="-1"/> </int-sftp:inbound-channel-adapter>
filename-regex="a.txt"是静态值,只能下载a.txt,而且需要手动启动/停止adapter,完全不适合用户触发的动态下载场景,所以替换为Outbound Gateway是最优解。
内容的提问来源于stack exchange,提问作者user55926




