我正在嘗試在事務結束時重命名遠程 sftp 服務器中的檔案并使用 Spring Boot 集成。在官方檔案中,他們提供了使用 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 中的有效負載。事務正在運行,但運算式計算在afterCommit和afterRollBack操作中失敗,并且檔案沒有被重命名。我在該方法org.springframework.expression.spel.standard.SpelExpression#getValue(org.springframework.expression.EvaluationContext, java.lang.Object) 中遇到以下錯誤:
EL1004E: 方法呼叫:在型別 com.jcraft.jsch.ChannelSftp$2 上找不到方法重命名(java.lang.String,java.lang.String)
這是我的實作:
@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);
}
我可以看到類ChannelSftp有一個.rename(String, String)方法并且是有效載荷的型別,但似乎 SpEL 無法看到從 GenericMessage 到 ChannelSftp 的轉換,因此看不到 .rename(String,字串)方法。我花了一天的時間試圖在檔案中找到一些沒有成功的東西,任何幫助將不勝感激。
謝謝
uj5u.com熱心網友回復:
你的問題在這里:com.jcraft.jsch.ChannelSftp$2。注意那個$2。這已經不是ChannelSftp,而是InputStream遠程檔案的內部檔案。而這正是SftpStreamingMessageSource正在產生的。它不回傳檔案,也不回傳ChannelSftp. 你不能打電話rename()的InputStream。
考慮改用特殊的IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE標頭。這是一個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')"));
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/361868.html
上一篇:Spring-后映射
下一篇:休眠錯誤訊息:重繪前保存瞬態實體
