如何通过Swagger UI向Cloud Foundry上的Spring Batch传CSV文件演示
我来帮你梳理下实现「CSV文件→Swagger UI→Rest Controller→Spring Batch」这个流程的具体步骤,亲测可行,你可以一步步落地:
1. 配置Spring Boot支持文件上传
首先要确保Spring Boot能处理文件上传请求,默认的文件大小限制可能偏小,建议在配置文件(application.yml或application.properties)里调整参数:
spring: servlet: multipart: max-file-size: 10MB # 单个文件最大大小,根据你的需求调整 max-request-size: 10MB # 整个请求的最大大小
2. 编写接收文件的Rest Controller
创建一个Controller,负责接收Swagger上传的CSV文件,临时保存后触发Spring Batch作业,同时把文件路径作为作业参数传递:
@RestController @RequestMapping("/batch") public class BatchJobController { private final JobLauncher jobLauncher; private final Job csvProcessingJob; // 构造注入JobLauncher和自定义的Batch作业 public BatchJobController(JobLauncher jobLauncher, Job csvProcessingJob) { this.jobLauncher = jobLauncher; this.csvProcessingJob = csvProcessingJob; } @PostMapping("/upload-and-run") public ResponseEntity<String> uploadAndRunJob(@RequestParam("file") MultipartFile file) throws Exception { if (file.isEmpty()) { return ResponseEntity.badRequest().body("请上传非空的CSV文件"); } // 将上传的文件保存到临时目录,作业完成后自动删除 File tempFile = File.createTempFile("batch-upload-", ".csv"); file.transferTo(tempFile); tempFile.deleteOnExit(); // 构建作业参数:传递临时文件路径,加timestamp确保每次作业参数唯一(避免重复执行) JobParameters jobParameters = new JobParametersBuilder() .addString("inputFilePath", tempFile.getAbsolutePath()) .addLong("timestamp", System.currentTimeMillis()) .toJobParameters(); // 触发批处理作业 jobLauncher.run(csvProcessingJob, jobParameters); return ResponseEntity.ok("批处理作业已启动,正在处理你的CSV文件"); } }
3. 修改Spring Batch的ItemReader,动态读取上传的文件
原来的ItemReader是固定读取类路径下的文件,现在要改成从作业参数里获取文件路径,这里需要用到@StepScope注解,让Reader能在Step级别动态获取参数:
@Bean @StepScope // 关键:让Bean能访问JobParameters public FlatFileItemReader<YourDataModel> csvItemReader( @Value("#{jobParameters['inputFilePath']}") String inputFilePath) { FlatFileItemReader<YourDataModel> reader = new FlatFileItemReader<>(); // 替换原来的ClassPathResource,改用FileSystemResource读取临时文件 reader.setResource(new FileSystemResource(inputFilePath)); // 下面的lineMapper、fieldSetMapper等原有配置保持不变 reader.setLineMapper(new DefaultLineMapper<>() {{ setLineTokenizer(new DelimitedLineTokenizer() {{ setNames("field1", "field2", "field3"); // 你的CSV字段名 }}); setFieldSetMapper(new BeanWrapperFieldSetMapper<>() {{ setTargetType(YourDataModel.class); // 你的数据模型类 }}); }}); return reader; }
4. 配置Swagger支持文件上传
如果用的是springdoc-openapi(Spring Boot 3.x推荐),只需在Controller方法上添加注解,让Swagger UI识别文件上传参数:
@PostMapping("/upload-and-run") @Operation(summary = "上传CSV文件并启动批处理作业", description = "上传本地CSV文件,系统将自动触发Spring Batch作业处理该文件") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "作业已成功启动"), @ApiResponse(responseCode = "400", description = "上传的文件为空,请重新选择") }) public ResponseEntity<String> uploadAndRunJob( @Parameter(description = "要上传的CSV文件", required = true) @RequestParam("file") MultipartFile file) throws Exception { // 方法体不变 }
启动应用后访问/swagger-ui.html,就能看到带文件上传表单的接口了,直接选择本地CSV文件即可测试。
5. Cloud Foundry部署的注意事项
- 临时文件处理:Cloud Foundry的临时目录是可读可写的,上面的
deleteOnExit()能在JVM退出时删除临时文件,但如果你的作业是异步执行的,建议在JobExecutionListener里手动删除文件:
@Bean public JobExecutionListener tempFileCleanupListener() { return new JobExecutionListener() { @Override public void afterJob(JobExecution jobExecution) { String filePath = jobExecution.getJobParameters().getString("inputFilePath"); if (filePath != null) { new File(filePath).delete(); } } }; }
然后把这个Listener加到你的Job配置里:
@Bean public Job csvProcessingJob(Step csvProcessingStep, JobExecutionListener tempFileCleanupListener) { return jobBuilderFactory.get("csvProcessingJob") .incrementer(new RunIdIncrementer()) .listener(tempFileCleanupListener) .flow(csvProcessingStep) .end() .build(); }
- 资源配额:确保你的Cloud Foundry应用有足够的磁盘配额(至少大于你要上传的最大文件大小),避免因磁盘不足导致文件保存失败。
内容的提问来源于stack exchange,提问作者Santosh Kashyap
相关产品推荐
相关产品推荐

