我原本期望ftp同步机制更新已更改的文件.但是,从我在这里看到的,只有在文件尚不存在的情况下才会下载该文件.就目前而言,即使时间戳/内容已更改,也不会在本地保存文件.
所以这是我到目前为止所发现的:
类org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer
@Override
public void synchronizeToLocalDirectory(final File localDirectory) {
final String remoteDirectory = this.remoteDirectoryExpression.getValue(this.evaluationContext, String.class);
try {
int transferred = this.remoteFileTemplate.execute(new SessionCallback<F, Integer>() {
@Override
public Integer doInSession(Session<F> session) throws IOException {
F[] files = session.list(remoteDirectory);
if (!ObjectUtils.isEmpty(files)) {
List<F> filteredFiles = filterFiles(files);
for (F file : filteredFiles) {
try {
if (file != null) {
copyFileToLocalDirectory(
remoteDirectory, file, localDirectory,
session);
}
}
catch (RuntimeException e) {
if (AbstractInboundFileSynchronizer.this.filter instanceof ReversibleFileListFilter) {
((ReversibleFileListFilter<F>) AbstractInboundFileSynchronizer.this.filter)
.rollback(file, filteredFiles);
}
throw …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 SFTP 将 excel 文件从本地 Windows PC 上传到 linux 机器。
这是我的代码:
private void uploadToSftp() {
try
{
ChannelSftp sftpClient = null;
Channel channel = null;
JSch jsch = new JSch();
Session session = jsch.getSession("username", "host", 22);
session.setPassword("password");
Properties config = new Properties();
config.put("StrictHostKeyChecking","no");
session.setConfig(config);
session.connect();
channel = session.openChannel("sftp");
channel.connect();
sftpClient = (ChannelSftp) channel;
sftpClient.cd("/var/www/folder");
File localFile = new File("C:\\Workspace\\upload-file\\test.xlsx");
sftpClient.put(localFile.getAbsolutePath(),localFile.getName());
sftpClient.disconnect();
channel.disconnect();
session.disconnect();
} catch (JSchException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
但每次我运行这个应用程序时,我都会收到错误消息:
3: Permission …Run Code Online (Sandbox Code Playgroud) 作为问题的后续行动 -
同样的文件在spring-ftp中一次又一次地被拾取,但名称不同
我的application.xml中有以下配置
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:int="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:file="http://www.springframework.org/schema/integration/file"
xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
xmlns:int-ftp="http://www.springframework.org/schema/integration/ftp"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/file
http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
http://www.springframework.org/schema/integration/stream
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
http://www.springframework.org/schema/integration/ftp
http://www.springframework.org/schema/integration/ftp/spring-integration-ftp.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<int:poller id="poller" task-executor="synchTaskExecutor" default="true" fixed-delay="1000" />
<beans:bean id="ftpClientFactory"
class="com.everge.springframework.integration.ftp.session.EvergeFtpSessionFactory">
<beans:property name="host" value="111.93.128.170"/>
<beans:property name="port" value="21"/>
<beans:property name="username" value="singha"/>
<beans:property name="password" value="singha16"/>
<beans:property name="clientMode" value="2"></beans:property>
</beans:bean>
<beans:bean id="ftpOutClientFactory"
class="org.springframework.integration.ftp.session.DefaultFtpSessionFactory">
<beans:property name="host" value="111.93.128.170"/>
<beans:property name="port" value="21"/>
<beans:property name="username" value="singha"/>
<beans:property name="password" value="singha16"/>
<beans:property name="clientMode" value="2"></beans:property>
</beans:bean>
<beans:bean id="synchTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<beans:property name="corePoolSize" value="1"></beans:property>
<beans:property name="maxPoolSize" value="1"></beans:property>
<beans:property …Run Code Online (Sandbox Code Playgroud) spring spring-integration spring-batch spring-integration-sftp
无法将文件发送到 SFTP 服务器。我没有从下面的日志中找到确切的问题。使用Spring 集成 SFTP 配置将我的文件发送到客户端实例。我已引用此链接https://blog.pavelsklenar.com/spring-integration-sftp-upload-example/进行实施。我在这里做错了什么。任何帮助将不胜感激,谢谢。
下面是代码片段
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost(sftpHost);
factory.setPort(sftpPort);
factory.setUser(sftpUser);
factory.setPassword(sftpPasword);
factory.setAllowUnknownKeys(true);
Run Code Online (Sandbox Code Playgroud)
请参阅下面的日志
10-12-2018 03:03:22.261 [task-scheduler-1] INFO org.springframework.integration.sftp.session.DefaultSftpSessionFactory.promptYesNo - The authenticity of host 'example.com' can't be established.
RSA key fingerprint is d1:e9:4e:64:a8:e5:19:46:7a:0e:79:2d:bf:27:cb:4c.
Are you sure you want to continue connecting?
10-12-2018 03:03:22.264 [task-scheduler-1] DEBUG org.springframework.integration.sftp.session.DefaultSftpSessionFactory.promptYesNo - No UserInfo provided - The authenticity of host 'example.com' can't be established.
RSA key fingerprint is d1:e9:4e:64:a8:e5:19:46:7a:0e:79:2d:bf:27:cb:4c.
Are you sure you want to continue connecting?, …Run Code Online (Sandbox Code Playgroud) 我在用着
我正在尝试设置一个 SFTP 出站适配器,该适配器允许我将文件移动到远程系统上的目录,并删除或重命名本地系统中的文件。
因此,例如,我想将文件a.txt放在本地目录中,并将其通过 SFTP 传输到目录inbound中的远程服务器。传输完成后,我想要a.txt的本地副本删除或重命名
我正在考虑几种方法。所以这是我用于测试的常用SessionFactory。
protected SessionFactory<ChannelSftp.LsEntry> buildSftpSessionFactory() {
DefaultSftpSessionFactory sessionFactory = new DefaultSftpSessionFactory();
sessionFactory.setHost("localhost");
sessionFactory.setUser("user");
sessionFactory.setAllowUnknownKeys(true);
sessionFactory.setPassword("pass");
CachingSessionFactory<ChannelSftp.LsEntry> cachingSessionFactory = new CachingSessionFactory<>(sessionFactory, 1);
return cachingSessionFactory;
}
Run Code Online (Sandbox Code Playgroud)
这是一个转换器,我必须将一些标头添加到消息中
@Override
public Message<File> transform(Message<File> source) {
System.out.println("here is the thing : "+source);
File file = (File)source.getPayload();
Message<File> transformedMessage = MessageBuilder.withPayload(file)
.copyHeaders(source.getHeaders())
.setHeaderIfAbsent(FileHeaders.ORIGINAL_FILE, file)
.setHeaderIfAbsent(FileHeaders.FILENAME, file.getName())
.build();
return transformedMessage;
}
Run Code Online (Sandbox Code Playgroud)
然后,我有一个集成流程,它使用轮询器来监视本地目录并调用它:
@Bean
public IntegrationFlow pushTheFile(){ …Run Code Online (Sandbox Code Playgroud) 我们正在开发一个 Spring Batch 应用程序,它将在未来处理“大”文件。为了保持低内存签名,我们在这些文件的尽可能小的块上使用 Spring Batch。处理后,我们希望将结果写回SFTP,这也会发生在输入文件的每个块中。
目前的做法如下:
StepExecutionListener.before()SftpOutboundAdapter:我们向with和空负载发送消息FileExistsMode.REPLACE以创建一个空文件(with .writing)
Reader:将读取输入文件
Processor:将使用结果增强输入并返回字符串列表
Writer:将字符串列表发送给SftpOutboundAdapter另一个FileExistsMode.APPEND
StepExecutionListener.after():如果执行成功,我们将重命名该文件以删除后缀.writing。
现在我看到有Streaming Inbound Adapters但我找不到Streaming Outbound Adapters。这真的是通过附加解决它的唯一/最好的方法吗?或者是否可以流式传输文件内容?
我们使用 Spring SFTP(出站)和网关将文件传输到多个目的地。但通常很少有文件被发送到错误的目的地。找不到任何线索,因为除了发送文件后的文件计数错误之外,我们的日志中没有收到任何错误。
这是我们的配置:
@Configuration
public class BankWiseSFTPConfig {
private final ExpressionParser EXPRESSION_PARSER;
private final BankConfigService bankConfigService;
public BankWiseSFTPConfig(BankConfigService bankConfigService) {
this.EXPRESSION_PARSER = new SpelExpressionParser();
this.bankConfigService = bankConfigService;
}
@Bean
public DelegatingSessionFactory<LsEntry> sessionFactory() {
List<BankConfigEntity> bankList = bankConfigService.getAll();
Map<Object, SessionFactory<LsEntry>> factories = new LinkedHashMap<>();
for (BankConfigEntity bank : bankList) {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory();
factory.setHost(bank.getSftpHost());
factory.setUser(bank.getSftpUser());
factory.setPort(bank.getSftpPort());
factory.setPassword(bank.getSftpPass());
factory.setAllowUnknownKeys(true);
factories.put(bank.getBankName(), factory);
}
bankList.clear();
return new DelegatingSessionFactory<LsEntry>(factories, factories.values().iterator().next());
}
@ServiceActivator(inputChannel = "toSftp")
@Bean
public SftpMessageHandler handler() {
SftpMessageHandler …Run Code Online (Sandbox Code Playgroud) 我想get通过 SFTP 使用 SFTP 出站网关访问文件,但我只找到使用 XML 配置的示例。如何使用 Java 配置来完成此操作?
更新(感谢 Artem Bilan 帮助)
我的配置类:
@Configuration
public class MyConfiguration {
@Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
DefaultSftpSessionFactory sftpSessionFactory = new DefaultSftpSessionFactory();
sftpSessionFactory.setHost("myhost");
sftpSessionFactory.setPort(22);
sftpSessionFactory.setUser("uname");
sftpSessionFactory.setPassword("pass");
sftpSessionFactory.setAllowUnknownKeys(true);
return new CachingSessionFactory<LsEntry>(sftpSessionFactory);
}
@Bean
@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler handler() {
SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sftpSessionFactory(), "get", "#getPayload() == '/home/samadmin/test.endf'");
sftpOutboundGateway.setLocalDirectory(new File("C:/test/gateway/"));
return sftpOutboundGateway;
}
}
Run Code Online (Sandbox Code Playgroud)
我的应用类:
@SpringBootApplication
@EnableIntegration
public class TestIntegrationApplication {
public static void main(String[] args) {
SpringApplication.run(TestIntegrationApplication.class, args);
} …Run Code Online (Sandbox Code Playgroud) 当使用 Spring Integration 的 SFTP 会话工厂(带有 Java 配置)时,我想动态设置远程 SFTP 服务器目录。Spring 文档说这是可能的:
SpEL 和 SFTP 出站适配器
remote-directory-expression与 Spring Integration 中的许多其他组件一样,在配置 SFTP 出站通道适配器时,您可以通过指定两个属性和remote-filename-generator-expression(参见上文)从 Spring 表达式语言 (SpEL) 支持中受益 。表达式求值上下文将以 Message 作为其根对象,从而允许您提供可以根据 Message 中的数据(来自有效负载或headers )动态计算文件名或现有目录路径的表达式。在上面的示例中,我们使用 表达式值定义属性,该表达式值根据原始名称计算文件名,同时附加后缀: - foo。remote-filename-generator-expression
但我在实施这一点时遇到了麻烦。我似乎找不到使用 Spring 的 SpEL 表达式语言的好例子。下面的代码有效,并将我的文件发送到根目录(如下所示),或者发送到特定目录(如果我在 LiteralExpression 中输入一个目录)。但我想用使用“路径”标头的 SpelExpression 替换 LiteralExpression 表达式,类似于我对动态调整上传的文件名的“文件”标头所做的操作。
@Configuration
public class SftpConfig {
@Autowired
private SftpSettings sftpSettings;
@Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
DefaultSftpSessionFactory factory = new …Run Code Online (Sandbox Code Playgroud) 我使用 Spring Boot 开发了一个调度程序。该调度程序在本地虚拟机中创建文本文件并将这些文件上传到远程 FTP 位置。调度程序每天运行 5 个时间段。最后时段为晚上 11.45。问题是,在晚上 11.45,文件上传无法正常工作,但文件正在本地位置创建。日志包含在这里
2018-10-19 00:00:26.338 ERROR --- [task-scheduler-4] ework.integration.handler.LoggingHandler : org.springframework.messaging.MessageDeliveryException: Error handling message for file [/apps/logs/lesipay-scheduler/to_ctf/ClientCreation18102018_23.txt -> ClientCreation18102018_23.txt]; nested exception is org.springframework.messaging.MessagingException: Failed to write to '/logs/dumpfiles/to_ctf/ClientCreation18102018_23.txt.writing' while uploading the file; nested exception is org.springframework.core.NestedIOException: failed to write file; nested exception is 4: java.io.IOException: inputstream is closed, failedMessage=GenericMessage [payload=/apps/logs/lesipay-scheduler/to_ctf/ClientCreation18102018_23.txt, headers={id=e914c7a2-2b4c-74e2-92d6-b8158ed72874, timestamp=1539886500712}]
at org.springframework.integration.file.remote.RemoteFileTemplate$1.doInSession(RemoteFileTemplate.java:321)
at org.springframework.integration.file.remote.RemoteFileTemplate$1.doInSession(RemoteFileTemplate.java:283)
at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:435)
at org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:283)
at org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:273)
at org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:265)
at org.springframework.integration.file.remote.handler.FileTransferringMessageHandler.handleMessageInternal(FileTransferringMessageHandler.java:170)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.config.annotation.ServiceActivatorAnnotationPostProcessor$ReplyProducingMessageHandlerWrapper.handleRequestMessage(ServiceActivatorAnnotationPostProcessor.java:98)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
at …Run Code Online (Sandbox Code Playgroud) 根据此文档,找不到从远程 SFTP 重新下载本地删除文件的正确过程。
要求是删除已经从远程 SFTP 获取的本地文件,并在需要时使用 sftp-inbound-adapter(DSL 配置)重新获取相同的文件。在此实现,MetadataStore没有持续到任何外部系统,如PropertiesPersistingMetadataStore或Redis的元数据存储。因此,根据doc,MetadataStore存储在In-Memory 中。
找不到任何方法来删除该远程文件的元数据,MetadataStore以使用file_name. 并且没有任何线索,应该如何removeRemoteFileMetadata()实现这个回调(根据这个文档)。
配置类包含以下内容:
@Bean
public IntegrationFlow fileFlow() {
SftpInboundChannelAdapterSpec spec = Sftp.inboundAdapter(sftpConfig.getSftpSessionFactory())
.preserveTimestamp(true)
.patternFilter(Constants.FILE_NAME_CONVENTION)
.remoteDirectory(sftpConfig.getSourceLocation())
.autoCreateLocalDirectory(true)
.deleteRemoteFiles(false)
.localDirectory(new File(sftpConfig.getDestinationLocation()));
return IntegrationFlows
.from(spec, e -> e.id("sftpInboundAdapter").autoStartup(false)
.poller(Pollers.fixedDelay(5000).get()))
.channel(MessageChannels.direct().get())
.handle(message -> {
log.info("Fetching File : " + message.getHeaders().get("file_name").toString());
})
.get();
}
Run Code Online (Sandbox Code Playgroud)