title: Spring Integration FTP - Create dynamic directory with remote directory expression (Java config)
body: <p>When using Spring Integration's SFTP Session Factory (with Java config), I'd like to set the remote SFTP server directory dynamically.  The Spring docs say this is possible:</p>
  
  <p><a href="https://docs.spring.io/spring-integration/reference/html/sftp.html" rel="nofollow noreferrer">Spring Integration SFTP Adapters</a></p>
  
  <blockquote>
    <p><em>SpEL and the SFTP Outbound Adapter</em></p>
    
    <p>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
    <code>remote-directory-expression</code> and <code>remote-filename-generator-expression</code>
    (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 <em>file name</em> or the existing <strong><em>directory path</em></strong> based
    on the data in the Message (either from <em>payload</em> or <em>headers</em>). In the
    example above we are defining the <code>remote-filename-generator-expression</code>
    attribute with an expression value that computes the <em>file name</em> based
    on its original name while also appending a suffix: -<em>foo</em>.</p>
  </blockquote>
  
  <p>But I'm having troubles implementing this.  I can't seem to find a good example that uses Spring's SpEL expression language.  The code below works, and sends my files to the root directory as it is below, or a specific directory if I enter one in the LiteralExpression.  But I'd like to swap out the LiteralExpression expression with a SpelExpression that uses the "path" header, similar to what I've done with the "file" header which dynamically adjusts the filename being uploaded.</p>
  
  <pre><code>@Configuration
  public class SftpConfig {
  
  @Autowired
  private SftpSettings sftpSettings;
  
  @Bean
  public SessionFactory&lt;LsEntry&gt; 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&lt;LsEntry&gt;(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&lt;?&gt; 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);
  }
  }
  </code></pre>
  
  <p>To initiate the file upload I execute this code</p>
  
  <pre><code>@Autowired
  private UploadGateway gateway;
  
  byte[] file = "test".getBytes();
  path = "mydirectory";
  filename = "myfilename";
  gateway.upload(file, filename, path); // edited to correct parameter order error
  </code></pre>