Spring 集成 FTP - 使用远程目录表达式创建动态目录(Java 配置)

Spring Integration FTP - Create dynamic directory with remote directory expression (Java config)

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

Spring Integration SFTP Adapters

SpEL and the SFTP Outbound Adapter

As with many other components in Spring Integration, you can benefit from the Spring Expression Language (SpEL) support when configuring an SFTP Outbound Channel Adapter, by specifying two attributes remote-directory-expression and remote-filename-generator-expression (see above). The expression evaluation context will have the Message as its root object, thus allowing you to provide expressions which can dynamically compute the file name or the existing directory path based on the data in the Message (either from payload or headers). In the example above we are defining the remote-filename-generator-expression attribute with an expression value that computes the file name based on its original name while also appending a suffix: -foo.

但是我在执行这个时遇到了麻烦。我似乎找不到使用 Spring 的 SpEL 表达式语言的好例子。下面的代码有效,并将我的文件发送到下面的根目录,或者如果我在 LiteralExpression 中输入一个特定目录。但是我想用使用 "path" header 的 SpelExpression 替换 LiteralExpression 表达式,类似于我对动态调整的 "file" header 所做的正在上传的文件名。

@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

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

ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser()

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

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

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

Reference Manual 中查看更多信息。