[英]Spring SFTP Outbound Gateway: How to close the session after GET in Java Config?
I have written a piece of code which uses Spring SFTP Outbound gateway and performs a GET operation. 我编写了一段使用Spring SFTP出站网关并执行GET操作的代码。 The whole configuration is in JAVA (no XML). 整个配置是在JAVA(没有XML)。 I have made a caching session factory which allows a maximum of 10 sessions. 我已经建立了一个缓存会话工厂,最多允许10个会话。 Due to which after multiple GET request when it exceeds 10, GET request start failing. 由于多次GET请求超过10后,GET请求开始失败。
I read the docs and it was written to close the session after operation but i'm unable to figure out as to how to close this session in JAVA Configuration? 我阅读了文档,它是为了在操作后关闭会话而写的,但是我无法弄清楚如何在JAVA配置中关闭这个会话?
@org.springframework.integration.annotation.MessagingGateway
public interface FileOperationGateway {
@Gateway(requestChannel = "sftpChannelDownload")
InputStream downloadFromSftp(Message<Boolean> message);
}
@Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost(SFTP_HOST);
factory.setPort(SFTP_PORT);
factory.setUser(SFTP_USERNAME);
factory.setPassword(SFTP_PASSWORD);
factory.setAllowUnknownKeys(true);
return new CachingSessionFactory<LsEntry>(factory);
}
/**
* Bean for Caching the session
*
*/
@Bean
@Autowired
public CachingSessionFactory<LsEntry> cachingSessionFactory(SessionFactory<LsEntry> sftpSessionFactory) {
CachingSessionFactory<LsEntry> cachingSessionFactory = new CachingSessionFactory<>(sftpSessionFactory, 10);
cachingSessionFactory.setSessionWaitTimeout(SFTP_SESSION_TIMEOUT);
return cachingSessionFactory;
}
/**
* Bean for Remote File Template
*
* @return
* @throws Exception
*/
@Bean
@Autowired
public RemoteFileTemplate<LsEntry> remoteFileTemplateDesigner(CachingSessionFactory<LsEntry> csf) throws Exception {
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("'" + SFTP_LOCATION + "'");
SftpRemoteFileTemplate rft = new SftpRemoteFileTemplate(csf);
rft.setRemoteDirectoryExpression(expression);
rft.setRemoteFileSeparator("/");
rft.setFileNameGenerator((msg) -> {
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
Instant instant = timestamp.toInstant();
String fileNameFromHeader = msg.getHeaders().get(FileOperationConstants.FILE_HEADER_KEY).toString();
String newFileName;
if (fileNameFromHeader.lastIndexOf("/") != -1) {
newFileName = fileNameFromHeader.substring(fileNameFromHeader.lastIndexOf("/"));
} else if (fileNameFromHeader.lastIndexOf("\\") != -1) {
newFileName = fileNameFromHeader.substring(fileNameFromHeader.lastIndexOf("\\"));
} else
newFileName = fileNameFromHeader;
String fileNameOnly = newFileName.substring(0, newFileName.lastIndexOf("."));
String fileType = newFileName.substring(newFileName.lastIndexOf(".") + 1);
return (fileNameOnly + "__" + instant.toString() + "." + fileType);
});
rft.afterPropertiesSet();
return rft;
}
@Bean
@Autowired
@ServiceActivator(inputChannel = "sftpChannelDownload")
public SftpOutboundGatewaySpec downloadHandler(RemoteFileTemplate<LsEntry> rft) {
SftpOutboundGatewaySpec sogs = Sftp.outboundGateway(rft, FileOperationConstants.FILE_DOWNLOAD_COMMAND,
FileOperationConstants.FILE_DOWNLOAD_EXPRESSION);
sogs.options(Option.STREAM);
return sogs;
}
******UPDATE:****** ****** UPDATE:******
I created a new class with @messageEndpoint and placed the closeable session code in it. 我用@messageEndpoint创建了一个新类,并在其中放置了可关闭的会话代码。 I then called this handler from my service class (where i was consuming the stream)This worked: 然后我从我的服务类(我正在使用流)中调用此处理程序。这有效:
@MessageEndpoint
public class FileOperationCloseSessionMessageHandler {
@ServiceActivator(inputChannel = "sftpCloseSession")
public void closeSession(Message<Boolean> msg) throws IOException {
Closeable closeable = new IntegrationMessageHeaderAccessor(msg).getCloseableResource();
if (closeable != null) {
closeable.close();
}
}
}
Placed this line in @MessagingGateway annotated class 将此行放在@MessagingGateway注释类中
@Gateway(requestChannel = "sftpCloseSession")
void closeSession(Message<InputStream> msg);
And then called the gateway method from service class: 然后从服务类调用网关方法:
Message<InputStream> msg = msgGateway.downloadFromSftp(message);
InputStream is = msg.getPayload();
msgGateway.closeSession(msg);
sogs.options(Option.STREAM); sogs.options(Option.STREAM);
When you stream the file, you are responsible for closing the session after you have finished streaming. 流式传输文件时,您负责在完成流式传输后关闭会话。 This is explained in the documentation . 这在文档中有解释。
When consuming remote files as streams, the user is responsible for closing the Session after the stream is consumed. 将远程文件作为流使用时,用户负责在使用流后关闭会话。 For convenience, the Session is provided in the IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE header, a convenience method is provided on the IntegrationMessageHeaderAccessor: 为方便起见,Session在IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE标头中提供,IntegrationMessageHeaderAccessor上提供了一种便捷方法:
Closeable closeable = new IntegrationMessageHeaderAccessor(message).getCloseableResource();
if (closeable != null) {
closeable.close();
}
Framework components such as the File Splitter and Stream Transformer will automatically close the session after the data is transferred. File Splitter和Stream Transformer等框架组件将在传输数据后自动关闭会话。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.