Error: EL1004E: Method call: Method rename(java.lang.String,java.lang.String) cannot be found on type com.jcraft.jsch.ChannelSftp$2

Error: EL1004E: Method call: Method rename(java.lang.String,java.lang.String) cannot be found on type com.jcraft.jsch.ChannelSftp$2

我正在尝试在事务结束时重命名远程 sftp 服务器中的文件并使用 Spring 启动集成。在官方 documentation 中,他们提供了使用 TransactionSynchronizationFactory 和 SpEL 表达式的示例,类似于:

    @Bean
public TransactionSynchronizationFactory transactionSynchronizationFactory(){

    ExpressionEvaluatingTransactionSynchronizationProcessor processor = new ExpressionEvaluatingTransactionSynchronizationProcessor();

    SpelExpressionParser spelParser = new SpelExpressionParser();
    processor.setAfterCommitExpression(spelParser.parseRaw(
            "payload.renameTo(headers['file_remoteDirectory']+'/'+headers['file_remoteFile'] ,headers['file_remoteDirectory']+'/'+headers['file_remoteFile']+'.PASSED')"));

    processor.setAfterRollbackExpression(spelParser.parseRaw(
            "payload.renameTo(headers['file_remoteDirectory']+'/'+headers['file_remoteFile'] ,headers['file_remoteDirectory']+'/'+headers['file_remoteFile']+'.FAILED')"));

    
    return new DefaultTransactionSynchronizationFactory(processor);
}

在我的实现中,我不使用 File 对象,而是使用 InputStream 作为 sftpAdapter 中的有效负载。事务正在运行,但表达式评估在 afterCommitafterRollBack 操作中失败,并且文件未被重命名。 我从该方法中遇到以下错误 org.springframework.expression.spel.standard.SpelExpression#getValue(org.springframework.expression.EvaluationContext, java.lang.Object) :

EL1004E: Method call: Method rename(java.lang.String,java.lang.String) cannot be found on type com.jcraft.jsch.ChannelSftp

这是我的实现:

    @Bean
@InboundChannelAdapter(channel = sftp-inChannel",
        poller = @Poller(value = "pollerMetadata"),
        autoStartup = "${sftp.autoStartup:true}")
public MessageSource<InputStream> ftpMessageSource() {
    SftpStreamingMessageSource source = new SftpStreamingMessageSource(sftpRemoteFileTemplate());
    source.setRemoteDirectory(path);
    source.setFilter(chainFilter());
    source.setMaxFetchSize(maxFetchSize);
    return source;
}


@Bean
public PollerMetadata pollerMetadata() {
    return Pollers.fixedRate(delayInMillisec)
            .maxMessagesPerPoll(maxFetchSize)
            .advice(transactionInterceptor())
            .transactionSynchronizationFactory(transactionSynchronizationFactory())
            .transactional()
            .get();
}



@Bean
public TransactionSynchronizationFactory transactionSynchronizationFactory(){

    ExpressionEvaluatingTransactionSynchronizationProcessor processor = new ExpressionEvaluatingTransactionSynchronizationProcessor();

    SpelExpressionParser spelParser = new SpelExpressionParser();
    processor.setAfterCommitExpression(spelParser.parseRaw(
            "payload.rename(headers['file_remoteDirectory']+'/'+headers['file_remoteFile'] ,headers['file_remoteDirectory']+'/'+headers['file_remoteFile']+'.PASSED')"));

    processor.setAfterRollbackExpression(spelParser.parseRaw(
            "payload.rename(headers['file_remoteDirectory']+'/'+headers['file_remoteFile'] ,headers['file_remoteDirectory']+'/'+headers['file_remoteFile']+'.FAILED')"));

    
    return new DefaultTransactionSynchronizationFactory(processor);
}

我可以看到 class ChannelSftp 有一个 .rename(String, String) 方法并且是有效载荷的类型,但似乎 SpEL 无法看到从 GenericMessage 到 ChannelSftp 的转换,因此看不到 .rename(String, String) 方法。 我花了一天时间试图在文档中找到一些东西 w/out 成功,任何帮助将不胜感激。

谢谢

您的问题在这里:com.jcraft.jsch.ChannelSftp。注意那个</code>。这已经不是 <code>ChannelSftp,而是远程文件的内部 InputStream。而这正是 SftpStreamingMessageSource 所产生的。它没有 return 文件,也没有 ChannelSftp。您不能在 InputStream.

上调用 rename()

考虑改用特殊的 IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE header。这是 org.springframework.integration.file.remote.session.Session 的一个实例,它已经有一个必需的 rename(String pathFrom, String pathTo) 方法。但同样:这个将对远程文件执行此操作:

 processor.setAfterCommitExpression(spelParser.parseRaw(
            "headers.closeableResource.rename(headers['file_remoteDirectory']+'/'+headers['file_remoteFile'] ,headers['file_remoteDirectory']+'/'+headers['file_remoteFile']+'.PASSED')"));