Spring integration 从SFTP出站网关获取输入流时没有消息
有时从SFTP出站网关获取输入流时没有消息 这是后续问题 我在前面的问题中遇到的问题是,我没有像int:service activator中所示关闭流。然而,当我添加int:service激活器时,我似乎被迫添加int:poller 然而,当我添加int:poller时,我注意到有时现在在尝试获取流时,消息是空的。我发现一种解决方法是简单地重试。我用不同的文件进行了测试,似乎小文件会受到不利影响,而大文件则不会。因此,如果我不得不猜测,肯定存在一个竞争条件,在我尝试调用getInputStream()之前int:service activator正在关闭会话,但我希望有人能解释这是否是实际发生的情况,以及是否有比重试更好的解决方案 谢谢 以下是出站网关配置:Spring integration 从SFTP出站网关获取输入流时没有消息,spring-integration,Spring Integration,有时从SFTP出站网关获取输入流时没有消息 这是后续问题 我在前面的问题中遇到的问题是,我没有像int:service activator中所示关闭流。然而,当我添加int:service激活器时,我似乎被迫添加int:poller 然而,当我添加int:poller时,我注意到有时现在在尝试获取流时,消息是空的。我发现一种解决方法是简单地重试。我用不同的文件进行了测试,似乎小文件会受到不利影响,而大文件则不会。因此,如果我不得不猜测,肯定存在一个竞争条件,在我尝试调用getInputStre
<int-ftp:outbound-gateway session-factory="ftpClientFactory"
request-channel="inboundGetStream" command="get" command-options="-stream"
expression="payload" remote-directory="/" reply-channel="stream">
</int-ftp:outbound-gateway>
<int:channel id="stream">
<int:queue/>
</int:channel>
<int:poller default="true" fixed-rate="50" />
<int:service-activator input-channel="stream"
expression="payload.toString().equals('END') ? headers['file_remoteSession'].close() : null" />
以下是我获取InputStream的源:
public InputStream openFileStream(final int retryCount, final String filename, final String directory)
throws Exception {
InputStream is = null;
for (int i = 1; i <= retryCount; ++i) {
if (inboundGetStream.send(MessageBuilder.withPayload(directory + "/" + filename).build(), ftpTimeout)) {
is = getInputStream();
if (is != null) {
break;
} else {
logger.info("Failed to obtain input stream so attempting retry " + i + " of " + retryCount);
Thread.sleep(ftpTimeout);
}
}
}
return is;
}
private InputStream getInputStream() {
Message<?> msgs = stream.receive(ftpTimeout);
if (msgs == null) {
return null;
}
InputStream is = (InputStream) msgs.getPayload();
return is;
}
public InputStream openFileStream(最终int retryCount、最终字符串文件名、最终字符串目录)
抛出异常{
InputStream=null;
for(int i=1;i msgs=stream.receive(ftpTimeout));
InputStream为=(InputStream)msgs.getPayload();
MessageHeaders mH=msgs.getHeaders();
Session Session=(Session)mH.get(“file_remoteSession”);
sss=新的SFTPStream会话(会话,is);
}
返回sss;
}
首先,您不需要
payload.toString().equals('END')
,因为看起来您在逻辑中没有使用
第二,你不需要那种难看的
,因为你可以完全访问代码中的消息。你只需获取文件\u remoteSession
,将其转换到会话中,并在逻辑结束时调用它的.close()
是的,存在竞争条件,但它发生在代码中
你看,你有流
队列频道
。从一开始你有一个消费者流。接收(ftpTimeout);
。但是现在你引入了
。因此又有一个竞争消费者。拥有如此小的(固定费率=“50”
)轮询间隔确实会导致您出现意外行为。谢谢您的帮助,但我在插入文档以执行我想要的操作时遇到了问题。因此,您的意思是我不需要xml中的
或
,但可以通过某种方式从Messag在我的getInputStream
方法中直接获取文件\u remoteSession
e
在我获得InputStream
之后?因此我似乎可以从消息头中获得文件\u remoteSession
。我可以在getInputStream
方法中获得输入流后调用close吗???如果您愿意,您可以。但是这是正确的吗?您应该在完成InputStream
时关闭它所有。例如,当您处理文件时,这一个与标准完全相似。因此,您应该处理来自该流的数据,并且只有在这之后才能关闭会话。否则,您将无法在关闭后处理该流。
public class SftpStreamSession {
private Session<?> session;
private InputStream inputStream;
public void close() {
inputStream.close();
session.close();
}
}
public SftpStreamSession openFileStream(final String filename, final String directory) throws Exception {
SftpStreamSession sss = null;
if (inboundGetStream.send(MessageBuilder.withPayload(directory + "/" + filename).build(), ftpTimeout)) {
Message<?> msgs = stream.receive(ftpTimeout);
InputStream is = (InputStream) msgs.getPayload();
MessageHeaders mH = msgs.getHeaders();
Session<?> session = (Session<?>) mH.get("file_remoteSession");
sss = new SftpStreamSession(session, is);
}
return sss;
}