Spring Batch — Upload Files to SFTP Server (Complete Guide)

Spring Batch — Upload Files to SFTP Server (Complete Guide)

Uploading files to an SFTP server is a very common enterprise batch requirement — daily reports, partner file exchanges, settlement files, and archival data. In this guide, you’ll learn how to implement a production-ready SFTP file upload job using Spring Batch and Spring Integration SFTP.

๐Ÿ“บ Video walkthrough: If you prefer learning visually, watch the full implementation explained step by step on YouTube:
๐Ÿ‘‰ Spring Batch SFTP File Upload – Complete Tutorial

๐Ÿ’ก Practice Tip: You can create a free SFTP server for testing and practice using https://sftpcloud.io/tools/free-sftp-server. This is perfect for local development and demos without setting up your own SFTP infrastructure.

Why use Tasklet for SFTP uploads?

  • SFTP uploads are usually file-oriented, not record-oriented
  • Tasklets provide full control over file existence, naming, and transfer logic
  • Simpler restart semantics compared to chunk-based processing
  • Ideal for single or small batches of files

Maven dependencies

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-batch</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework.integration</groupId>
  <artifactId>spring-integration-sftp</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

application.properties

spring.application.name=spring-batch-sftp-upload

spring.datasource.url=jdbc:oracle:thin:@localhost:1521/XEPDB1
spring.datasource.username=dbadmin
spring.datasource.password=dbadmin1
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver

spring.batch.job.enabled=false

sftp.host=eu-central-1.sftpcloud.io
sftp.port=22
sftp.username=your-username
sftp.password=your-password
sftp.remote-dir=/pub/example/

SFTP configuration

Spring Integration provides DefaultSftpSessionFactory and SftpRemoteFileTemplate to interact with an SFTP server.

@Configuration
public class SftpConfig {

  @Value("${sftp.host}")
  private String host;

  @Value("${sftp.port}")
  private int port;

  @Value("${sftp.username}")
  private String username;

  @Value("${sftp.password}")
  private String password;

  @Bean
  public DefaultSftpSessionFactory defaultSftpSessionFactory() {
    DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory();
    factory.setHost(host);
    factory.setPort(port);
    factory.setUser(username);
    factory.setPassword(password);
    factory.setAllowUnknownKeys(true);
    return factory;
  }

  @Bean
  public SftpRemoteFileTemplate sftpRemoteFileTemplate() {
    return new SftpRemoteFileTemplate(defaultSftpSessionFactory());
  }
}

Spring Batch Job configuration

This job uses a single tasklet-based step that uploads a file to the SFTP server.

@Configuration
public class SpringBatchConfig {

  @Bean
  public Step sftpUploadStep(JobRepository jobRepository,
                             PlatformTransactionManager transactionManager,
                             SftpUploadTasklet tasklet) {
    return new StepBuilder("sftpUploadStep", jobRepository)
      .tasklet(tasklet, transactionManager)
      .build();
  }

  @Bean
  public Job dailyFileJob(JobRepository jobRepository,
                          Step sftpUploadStep) {
    return new JobBuilder("dailyFileJob", jobRepository)
      .start(sftpUploadStep)
      .build();
  }
}

SFTP Upload Tasklet

The tasklet validates file existence, ensures the remote directory exists, and uploads the file using an SFTP session.

@Component
public class SftpUploadTasklet implements Tasklet {

  @Autowired
  private SftpRemoteFileTemplate sftpRemoteFileTemplate;

  @Override
  public RepeatStatus execute(StepContribution contribution,
                              ChunkContext chunkContext) throws Exception {

    File file = new File("F:/youtube-videos/LikeSubscribe.jpg");

    if (!file.exists()) {
      throw new RuntimeException("File does not exist");
    }

    sftpRemoteFileTemplate.execute(session -> {

      String remoteDir = "/pub/example";
      if (!session.exists(remoteDir)) {
        session.mkdir(remoteDir);
      }

      try (InputStream is = new FileInputStream(file)) {
        session.write(is, remoteDir + "/" + file.getName());
      }
      return null;
    });

    return RepeatStatus.FINISHED;
  }
}

REST API to trigger job

@RestController
@RequestMapping("/api/batch")
public class JobController {

  private final JobLauncher jobLauncher;
  private final Job dailyFileJob;

  public JobController(JobLauncher jobLauncher, Job dailyFileJob) {
    this.jobLauncher = jobLauncher;
    this.dailyFileJob = dailyFileJob;
  }

  @GetMapping("/trigger-sftp")
  public ResponseEntity<String> triggerSftpJob() {
    try {
      JobParameters params = new JobParametersBuilder()
        .addLong("startAt", System.currentTimeMillis())
        .toJobParameters();

      jobLauncher.run(dailyFileJob, params);
      return ResponseEntity.ok("SFTP Upload Job triggered successfully.");
    } catch (Exception e) {
      return ResponseEntity.internalServerError()
        .body("Job failed: " + e.getMessage());
    }
  }
}

Transactional behavior & restartability

  • If the tasklet fails, the step is marked as FAILED
  • Restarting the job re-executes the upload logic
  • Ensure idempotency to avoid duplicate uploads

Production best practices

  • Use temporary filenames and rename after upload
  • Enable retries for transient network failures
  • Prefer key-based authentication over passwords
  • Log upload metadata (file name, size, timestamp)
  • Validate file checksum after upload if required

FAQ

  • Why not use ItemWriter? Tasklets are simpler for file transfers.
  • Can I upload multiple files? Yes — iterate over a directory inside the tasklet.
  • Is SftpRemoteFileTemplate thread-safe? Yes, when used per execution.

Conclusion

Using Spring Batch with Spring Integration SFTP provides a clean and reliable way to upload files to external systems. Tasklet-based jobs are simple, flexible, and production-friendly for file transfer use cases.

๐ŸŽฅ Don’t forget to watch the full YouTube walkthrough:
Spring Batch SFTP File Upload – Step-by-Step Video Guide

๐Ÿงฑ Spring Batch Core Components

Understand how ItemReader, ItemProcessor, and ItemWriter work together when exporting data to CSV files.

๐Ÿ”„ Spring Batch ItemProcessor Example

Apply transformation and formatting logic before writing records into CSV output files.

๐Ÿ” CSV to Database with Spring Batch

Compare inbound (CSV → DB) and outbound (DB → CSV) batch processing patterns.

๐Ÿšซ Skip Policy & Error Handling

Handle write failures and formatting errors gracefully while exporting large datasets.

๐Ÿ”€ Conditional Flow in Spring Batch Jobs

Control job execution paths based on CSV generation success or failure.

๐Ÿงต Multithreaded Step in Spring Batch

Improve export performance by parallelizing data processing and CSV writing steps.