带有文件名的Spring批处理作业参数

Posted

技术标签:

【中文标题】带有文件名的Spring批处理作业参数【英文标题】:Spring batch Jobparamaters with file name 【发布时间】:2019-08-01 23:34:43 【问题描述】:

我想用 Spring Batch 控制器和动态输入文件名创建项目。

我的代码:休息控制器

@RestController

公共类 FileNameController

@Autowired
JobLauncher jobLauncher;

@Autowired
Job job;

@RequestMapping("/launchjob")
public String handle(@RequestParam("fileName") String fileName) throws Exception 

    Logger logger = LoggerFactory.getLogger(this.getClass());
    try 
        JobParameters jobParameters = new JobParametersBuilder()
                                                    .addString("input.file.name", fileName)
                                                    .addLong("time", System.currentTimeMillis())
                                                    .toJobParameters();
        jobLauncher.run(job, jobParameters);
     catch (Exception e) 
        logger.info(e.getMessage());
    

    return "Done";

作业配置:

@Configuration

@EnableBatchProcessing 公共类 JobConfig

@Autowired
public JobBuilderFactory jobBuilderFactory;

@Autowired
public StepBuilderFactory stepBuilderFactory;


 Filetasklet ft=new Filetasklet();
 Logger log = LoggerFactory.getLogger(this.getClass().getName());


private String pathFile = urlCoffreFort + "\\" + ft.getFileName();

// => Configuration of Job  
        @Bean
        public Job job() throws IOException 
                    return jobBuilderFactory.get("job")
                    .incrementer(new RunIdIncrementer())
                    .flow(step1())
                    .end()
                    .build();
        

        //###### Steps          
        // => Step cecStep1
        @Bean
        public Step step1() throws IOException 
            return stepBuilderFactory.get("fileDecrypt")
                    .<Person, String>chunk(100)
                    .reader(reader1())
                    .processor(processor1FileDecrypt())
                    .writer(writer1())
                    .faultTolerant()
                    .skip(Exception.class)
                    .skipLimit(100)
                    .build();
        
        // ####### readers 

        // => reader1()
        @Bean
        public FlatFileItemReader<Person> reader1() throws IOException

            return new FlatFileItemReaderBuilder<CSCivique>().name("personItemReader")
                                        .resource(new ClassPathResource(pathFile))
                                        .delimited()
                                        .delimiter(";")
                                        .names(new String[]  "id",  "nomNaissance", "prenom" )
                                        .targetType(CSCivique.class)
                                        .build();
        

        // ######Processors             

        @Bean
        public PersonItemProcessor1FileDecrypt processor1FileDecrypt() 
            return new PersonItemProcessor1FileDecrypt();
        

        // ######Writers 

        @Bean
        public FlatFileItemWriter<String> writer1() 
            return new FlatFileItemWriterBuilder<String>().name("greetingItemWriter")
                    .resource(new FileSystemResource("sav/greetings.csv"))
                    .lineAggregator(new PassThroughLineAggregator<>()).build();
        

当我写网址时: http://localhost:8080/launchjob?fileName=djecc5cpt.csv 控制台打印:

PreparedStatementCallback;错误的 SQL 语法 [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME =?和 JOB_KEY =?];嵌套异常是 org.postgresql.util.PSQLException:错误:关系“batch_job_instance”不存在 职位:39

【问题讨论】:

错误信息有什么不能理解的地方? 我没有请求,通常框架会创建它的表 我添加了一个答案,希望对您有所帮助。 【参考方案1】:

我没有请求,通常框架会创建它的表

Spring Batch 不会决定代表您在生产数据库中创建表。 需要提前做出决定并手动进行。否则,如果您使用 Spring Boot,您可以通过设置 spring.batch.initialize-schema=always 告诉 Spring Boot 为您执行此操作。

有关类似问题/答案,请参阅https://***.com/a/51891852/5019386。

【讨论】:

以上是关于带有文件名的Spring批处理作业参数的主要内容,如果未能解决你的问题,请参考以下文章

从 tasklet 步骤将参数添加到作业上下文并在 Spring Batch 的后续步骤中使用

Spring 批处理作业应仅在 Spring 集成文件轮询器轮询文件后执行一次

查询以包括 spring 批处理作业参数值以及作业执行数据

Spring JMS ActiveMQ 跟踪作业状态

如何获取Spring批处理作业参数并传递给sql

Spring 批处理作业应仅在 Spring 集成轮询器之后执行一次