Java 如何配置spring集成适配器以通过SFTP获取和放置文件

Java 如何配置spring集成适配器以通过SFTP获取和放置文件,java,spring-integration,sftp,spring-integration-dsl,Java,Spring Integration,Sftp,Spring Integration Dsl,我尝试使用Spring集成实现以下场景: 输入通道应轮询SFTP站点,以获取将其存储在本地“stfp入站”文件夹中的文件。 输出通道应将本地“sftp出站”文件夹中的现有文件推送到sftp站点。 我从输入通道开始。到目前为止,它一直在工作,但显然是非常静态的 这是我目前的配置: @Component public class SftpClient { private static final Logger LOG = LoggerFactory.getLogger(SftpClient.

我尝试使用Spring集成实现以下场景:

输入通道应轮询SFTP站点,以获取将其存储在本地“stfp入站”文件夹中的文件。 输出通道应将本地“sftp出站”文件夹中的现有文件推送到sftp站点。 我从输入通道开始。到目前为止,它一直在工作,但显然是非常静态的

这是我目前的配置:

@Component
public class SftpClient {
    private static final Logger LOG = LoggerFactory.getLogger(SftpClient.class);

@Bean
public IntegrationFlow sftpInboundFlow() {
    return IntegrationFlows
        .from(Sftp.inboundAdapter(sftpSessionFactory())
                .preserveTimestamp(true)
                .remoteDirectory("data")
                .regexFilter(".*\\.txt$")
//                    .localFilenameExpression("#this.toUpperCase() + '.a'")
                .localDirectory(new File("ftp-inbound")),
             e -> e.id("sftpInboundAdapter")
                .autoStartup(true)
                .poller(Pollers.fixedDelay(5000)))
        .handle(m -> System.out.println(m.getPayload()))
        .get();
}

@Bean
public IntegrationFlow sftpOutboundFlow() {
    return IntegrationFlows.from("toSftpChannel")
        .handle(Sftp.outboundAdapter(sftpSessionFactory(), FileExistsMode.FAIL)
                     .useTemporaryFileName(false)
                     .remoteDirectory("/data")
        ).get();
}

@Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
//      // with private key resource: catch MalformedURLException
//      try {
        DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
        factory.setHost("myHost");
        factory.setPort(22);
        factory.setUser("myUser");
        factory.setPassword("myPassword");
//          factory.setPrivateKey(new FileUrlResource("/Users/myUser/.ssh/id_rsa"));
//          factory.setPrivateKeyPassphrase("passphrase");
        factory.setAllowUnknownKeys(true);
        return new CachingSessionFactory<LsEntry>(factory);
//      }
//      catch (MalformedURLException e) {
//          throw new IllegalArgumentException("malformed URL");
//      }
}
@组件
公共类SftpClient{
私有静态最终记录器LOG=LoggerFactory.getLogger(SftpClient.class);
@豆子
公共集成流sftpInboundFlow(){
返回积分流
.from(Sftp.inboundAdapter(sftpSessionFactory())
.保留时间戳(true)
.remoteDirectory(“数据”)
.regexFilter(“.\\.txt$”)
//.localFilenameExpression(“#this.toUpperCase()+'.a'))
.localDirectory(新文件(“ftp入站”),
e->e.id(“sftpInboundAdapter”)
.AutoStart(真)
.poller(poller.fixedDelay(5000)))
.handle(m->System.out.println(m.getPayload()))
.get();
}
@豆子
公共集成流sftpOutboundFlow(){
返回IntegrationFlows.from(“toSftpChannel”)
.handle(Sftp.outboundAdapter(sftpSessionFactory(),FileExistsMode.FAIL)
.useTemporaryFileName(false)
.remoteDirectory(“/data”)
).get();
}
@豆子
公共会话工厂sftpSessionFactory(){
////使用私钥资源:捕获MalformedURLException
//试一试{
DefaultSftpSessionFactory=新的DefaultSftpSessionFactory(true);
factory.setHost(“myHost”);
工厂设置端口(22);
factory.setUser(“myUser”);
工厂设置密码(“我的密码”);
//setPrivateKey(新的FileUrlResource(“/Users/myUser/.ssh/id_rsa”);
//工厂。setPrivateKeyPassphrase(“passphrase”);
工厂。setAllowUnknownKeys(真);
返回新的CachingSessionFactory(工厂);
//      }
//捕获(格式错误){
//抛出新的IllegalArgumentException(“格式错误的URL”);
//      }
}
我需要一些建议来制定一个更具活力的方法。 我想象一个组件类,它使用公共方法sftpGet()sftpPut()来获取和放置文件,而通道是通过集成流创建的,集成流包含构成SFTP传输的必需参数:主机名、端口、用户、密码、远程目录、本地目录

我怎样才能做到这一点

我从一个类似的TCP/IP通道场景中得到了一个很好的提示,但我无法将这些解决方案转换为这个SFTP场景

请指教

在接受了Gary的建议后,我做了一个愚蠢的动态Bean:

@Component
public class DynamicSftpTemplate implements InputStreamCallback {
    private static Logger LOG = LoggerFactory.getLogger(DynamicSftpTemplate.class);

    private String localDir;
    private String localFilename;

    public void getSftpFile(String sessionId, String host, int port, String user, String password,
            String remoteDir, String remoteFilename, String localDir, String localFilename) {
        LOG.debug("getSftpFile sessionId={}", sessionId);
        ioSftpFile(GET, host, port, user, password,
                remoteDir, remoteFilename, localDir, localFilename);
    }

    public void putSftpFile(String sessionId, String host, int port, String user, String password,
            String remoteDir, String remoteFilename, String localDir, String localFilename) {
        LOG.debug("putSftpFile sessionId={}", sessionId);
        ioSftpFile(PUT, host, port, user, password,
                remoteDir, remoteFilename, localDir, localFilename);
    }

    public void rmSftpFile(String sessionId, String host, int port, String user, String password,
            String remoteDir, String remoteFilename) {
        LOG.debug("rmSftpFile sessionId={}", sessionId);
        ioSftpFile(RM, host, port, user, password, remoteDir, remoteFilename, null, null);
    }

    private void ioSftpFile(SftpOperationType op, String host, int port, String user, String password,
            String remoteDir, String remoteFilename, String localDir, String localFilename) {
        LOG.debug("ioSftpFile op={}, host={}, port={}", op, host, port);
        LOG.debug("ioSftpFile user={}, password={}", user, password);
        SftpRemoteFileTemplate template = new SftpRemoteFileTemplate(sftpSessionFactory(host, port, user, password));
        template.setFileNameExpression(new LiteralExpression(remoteDir + "/" + remoteFilename));
        template.setRemoteDirectoryExpression(new LiteralExpression(remoteDir));

        //template.afterPropertiesSet();
        this.localDir = localDir;
        this.localFilename = localFilename;
        if (op == GET) {
            // template.get(buildGetMessage(remoteDir, remoteFilename), (InputStreamCallback) this);
            template.get(remoteDir + "/" + remoteFilename, this);
        }
        else if (op == PUT) {
            template.send(buildPutMessage(remoteDir, remoteFilename), FileExistsMode.REPLACE);          
        }
        else if (op == RM) {
            template.remove(remoteDir + "/" + remoteFilename);          
        }
        else {
            throw new IllegalArgumentException("invalid sftp operation, " + op);
        }
    }

    private DefaultSftpSessionFactory sftpSessionFactory(String host, int port, String user, String password) {
        LOG.debug("sftpSessionFactory");
        DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
        factory.setHost(host);
        factory.setPort(port);
        factory.setUser(user);
        factory.setPassword(password);
        factory.setAllowUnknownKeys(true);
        return factory;
    }

    private Message<?> buildPutMessage(String remoteDir, String remoteFilename) {
        return MessageBuilder.withPayload(new File(this.localDir + "/" + this.localFilename))
                .setHeader("file_remoteDirectory", remoteDir)
                .setHeader("file_remoteFile", remoteFilename)
                .build();
    }

    public void doWithInputStream(InputStream is) throws IOException {
        LOG.debug("doWithInputStream");
        String fullPathName = this.localDir + "/" + this.localFilename;
        FileWriter w = new FileWriter(fullPathName);
        IOUtils.copy(is, w, "UTF-8");
        LOG.debug("doWithInputStream file {} written", fullPathName);
        w.close();
        is.close();
    }
}
@组件
公共类DynamicSftpTemplate实现InputStreamCallback{
私有静态记录器LOG=LoggerFactory.getLogger(dynamicsftpemplate.class);
私有字符串localDir;
私有字符串localFilename;
public void getSftpFile(字符串sessionId、字符串主机、int端口、字符串用户、字符串密码、,
字符串remoteDir、字符串remoteFilename、字符串localDir、字符串localFilename){
debug(“getSftpFile sessionId={}”,sessionId);
ioSftpFile(获取、主机、端口、用户、密码、,
remoteDir、remoteFilename、localDir、localFilename);
}
public void putstfpffile(字符串sessionId、字符串主机、int端口、字符串用户、字符串密码、,
字符串remoteDir、字符串remoteFilename、字符串localDir、字符串localFilename){
debug(“putstfpfile sessionId={}”,sessionId);
ioSftpFile(PUT、主机、端口、用户、密码、,
remoteDir、remoteFilename、localDir、localFilename);
}
public void rmSftpFile(字符串sessionId、字符串主机、int端口、字符串用户、字符串密码、,
字符串remoteDir,字符串remoteFilename){
调试(“rmSftpFile sessionId={}”,sessionId);
ioSftpFile(RM、主机、端口、用户、密码、remoteDir、remoteFilename、null、null);
}
私有void ioSftpFile(SftpOperationType op、字符串主机、int端口、字符串用户、字符串密码、,
字符串remoteDir、字符串remoteFilename、字符串localDir、字符串localFilename){
debug(“ioSftpFile op={},host={},port={}”,op,host,port);
debug(“ioSftpFile user={},password={}”,user,password);
SftpRemoteFileTemplate=新的SftpRemoteFileTemplate(sftpSessionFactory(主机、端口、用户、密码));
setFileNameExpression(新的LiteralExpression(remoteDir+“/”+remoteFilename));
setRemoteDirectoryExpression(新的LiteralExpression(remoteDir));
//template.afterPropertieSet();
this.localDir=localDir;
this.localFilename=localFilename;
if(op==GET){
//get(buildGetMessage(remoteDir,remoteFilename),(InputStreamCallback)this);
get(remoteDir+“/”+remoteFilename,this);
}
else if(op==PUT){
发送(buildPutMessage(remoteDir,remoteFilename),FileExistsMode.REPLACE);
}
否则如果(op==RM){
删除(remoteDir+“/”+remoteFilename);
}
否则{
抛出新的IllegalArgumentException(“无效的sftp操作,”+op);
}
}
私有DefaultSftpSessionFactory sftpSessionFactory(字符串主机、int端口、字符串用户、字符串密码){
LOG.debug(“sftpSessionFactory”);
DefaultSftpSessionFactory=新的DefaultSftpSessionFactory(true);
setHost(主机);
工厂设置端口(端口);
工厂设置用户(用户);
出厂设置密码(密码);
工厂。setAllowUnknownKeys(真);
返回工厂;
}
私有消息buildPutMessage(字符串remoteDir,字符串remoteFilename){
返回消息