2

使用 Spring Integration 的 SFTP 会话工厂(使用 Java 配置)时,我想动态设置远程 SFTP 服务器目录。Spring 文档说这是可能的:

Spring 集成 SFTP 适配器

SpEL 和 SFTP 出站适配器

与 Spring Integration 中的许多其他组件一样,您可以在配置 SFTP 出站通道适配器时从 Spring 表达式语言 (SpEL) 支持中受益,方法是指定两个属性 remote-directory-expressionremote-filename-generator-expression (见上文)。表达式评估上下文将 Message 作为其根对象,因此允许您提供可以根据 Message 中的数据(来自payloadheaders )动态计算文件名或现有目录路径的表达式。在上面的示例中,我们使用表达式值定义 属性,该表达式值根据其原始名称计算文件名,同时还附加一个后缀: - fooremote-filename-generator-expression.

但我在实现这一点时遇到了麻烦。我似乎找不到使用 Spring 的 SpEL 表达式语言的好例子。下面的代码有效,并将我的文件发送到下面的根目录,或者如果我在 LiteralExpression 中输入一个特定目录,则发送到特定目录。但我想用使用“路径”标题的 SpelExpression 替换 LiteralExpression 表达式,类似于我对动态调整正在上传的文件名的“文件”标题所做的事情。

@Configuration
public class SftpConfig {

@Autowired
private SftpSettings sftpSettings;

@Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
    DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
    factory.setHost(sftpSettings.getHostname());
    factory.setPort(sftpSettings.getPort());
    factory.setUser(sftpSettings.getUsername());
    factory.setPassword(sftpSettings.getPassword());
    factory.setAllowUnknownKeys(true);
    return new CachingSessionFactory<LsEntry>(factory);
}

@Bean
@ServiceActivator(inputChannel = "toSftpChannel")
public MessageHandler handler() {
    SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory());
    handler.setAutoCreateDirectory(true);                               // automatically create the remote directory
    handler.setRemoteDirectoryExpression(new LiteralExpression(""));
    handler.setFileNameGenerator(new FileNameGenerator() {
        @Override
        public String generateFileName(Message<?> message) {
            return (String) message.getHeaders().get("filename");
        }
    });
    return handler;
}

@MessagingGateway
public interface UploadGateway {

    @Gateway(requestChannel = "toSftpChannel")
    void upload(@Payload byte[] file, @Header("filename") String filename, @Header("path") String path);
}
}

要启动文件上传,我执行此代码

@Autowired
private UploadGateway gateway;

byte[] file = "test".getBytes();
path = "mydirectory";
filename = "myfilename";
gateway.upload(file, filename, path); // edited to correct parameter order error
4

1 回答 1

4

SpEL 表达式可以非常复杂和动态。为此,您必须声明解析器:

ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser()

并将其用于此表达式解析:

handler.setRemoteDirectoryExpression(EXPRESSION_PARSER.parseExpression("headers['path']"));

并且结果Expression对象将根据每个请求消息进行评估。

在参考手册中查看更多信息。

于 2017-10-09T16:02:09.860 回答