我编写了一段使用Spring SFTP出站网关并执行GET操作的代码。整个配置是在JAVA(没有XML)。 我已经建立了一个缓存会话工厂,最多允许10个会话。由于多次GET请求超过10后,GET请求开始失败。
我阅读了文档,它是为了在操作后关闭会话而编写的,但我无法弄清楚如何在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:******
我使用@messageEndpoint创建了一个新类,并在其中放置了可关闭的会话代码。然后我从我的服务类(我正在使用流)中调用此处理程序。这工作:
@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();
}
}
}
将此行放在@MessagingGateway注释类
中@Gateway(requestChannel = "sftpCloseSession")
void closeSession(Message<InputStream> msg);
然后从服务类调用网关方法:
Message<InputStream> msg = msgGateway.downloadFromSftp(message);
InputStream is = msg.getPayload();
msgGateway.closeSession(msg);
答案 0 :(得分:0)
sogs.options(Option.STREAM);
当您流式传输文件时,您负责在完成流式传输后关闭会话。这在the documentation中解释。
当将远程文件作为流使用时,用户负责在使用流之后关闭会话。为方便起见,Session在IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE标头中提供,IntegrationMessageHeaderAccessor上提供了一种便捷方法:
Closeable closeable = new IntegrationMessageHeaderAccessor(message).getCloseableResource();
if (closeable != null) {
closeable.close();
}
File Splitter和Stream Transformer等框架组件将在传输数据后自动关闭会话。