如何为 int-sftp:outbound-gateway 动态创建会话工厂?

How to create session-factory dynamically for int-sftp:outbound-gateway?

我正在尝试使用 int-sftp:outbound-gateway 实现安全文件传输。 我当前的配置如下所示:

<bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
  <constructor-arg name="isSharedSession" value="false" />

<int:chain id="sftpGetRequestEnricherChain" input-channel="sftpGetRequestEnricherChannel" output-channel="sftpGetRequestChannel">
      <int-xml:xpath-header-enricher id="sftpHostEnricher">
         <int-xml:header name="sftp_host" xpath-expression="/fileGetRequest/property[@name='host']/@val" />
         <int-xml:header name="sftp_port" xpath-expression="/fileGetRequest/property[@name='port']/@val" />
         <int-xml:header name="sftp_user" xpath-expression="/fileGetRequest/property[@name='user']/@val" />
         <int-xml:header name="source_directory" xpath-expression="/fileGetRequest/property[@name='sourceDirectory']/@val" />
         <int-xml:header name="source_file_name" xpath-expression="/fileGetRequest/property[@name='sourceFileName']/@val" />
      </int-xml:xpath-header-enricher>
      <int:service-activator ref="refreshSftpSessionFactoryTask" />
   </int:chain>

<bean name="refreshSftpSessionFactoryTask" class="com.mycorp.filetransfer.RefreshSftpSessionFactoryTask" />

<int-sftp:outbound-gateway id="sftpGetOutboundGateway" 
      local-directory="${sftp.local.directory.get}"
      session-factory="sftpSessionFactory"
      request-channel="sftpGetRequestChannel"
      reply-channel="logChannel"
      command="get"
      expression="headers['source_directory'] + '/' + headers['source_file_name']" />

如上所示,每条消息都包含主机、端口、用户和文件路径详细信息。

在 RefreshSftpSessionFactoryTask 中,我正在设置主机、端口和用户详细信息并获取密码并将其设置在 sftpSessionFactory bean 中,如下所示:

AbstractApplicationContext context = new ClassPathXmlApplicationContext(SFTP_CONFIG_FILE, this.getClass());
DefaultSftpSessionFactory sftpSessionFactory = context.getBean("sftpSessionFactory", DefaultSftpSessionFactory.class);

sftpSessionFactory.setHost(host);
sftpSessionFactory.setPort(port);
sftpSessionFactory.setUser(user);
sftpSessionFactory.setPassword(fetchPassword());
context.close();

但是,在文件传输过程中,我收到一个异常 "host must not be null in sftpSessionFactory"。

应该怎样做才能正确设置 DefaultSftpSessionFactory 中的属性并让 int-sftp:outbound-gateway 看到这些属性?

您每次都在创建一个新的会话工厂并完全销毁它;您没有更新现有的。

而不是

AbstractApplicationContext context = new ClassPathXmlApplicationContext(SFTP_CONFIG_FILE, this.getClass());
DefaultSftpSessionFactory sftpSessionFactory = context.getBean("sftpSessionFactory", DefaultSftpSessionFactory.class);

只需将 setSessionFactory(DefaultSftpSessionFactory factory) 添加到您的 RefreshSftpSessionFactoryTask

然后

<bean name="refreshSftpSessionFactoryTask" class="com.mycorp.filetransfer.RefreshSftpSessionFactoryTask">
   <property name="sessionFactory" ref="sftpSessionFactory" />
</bean>

将会话工厂存储在字段中并使用...

this.sftpSessionFactory.setHost(host);
this.sftpSessionFactory.setPort(port);
this.sftpSessionFactory.setUser(user);
this.sftpSessionFactory.setPassword(fetchPassword());

...您将更新适配器使用的会话工厂。

不过,您需要非常小心线程。此技术在多线程环境中不起作用。