未注入作业参数,并且在春季批处理中skiplistener不起作用

问题描述 投票:0回答:1

第一个问题是当我打印Job参数“ errorPathFile”的值时,它为null。

package com.diatoz.demo.configuration;

import java.io.FileWriter;
import java.io.IOException;

import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;

import com.diatoz.demo.domain.Employee;

@Component
@Scope(value = "step")
public class EmployeeFieldSetMapper implements FieldSetMapper<Employee> {

    @Value("#{jobParameters['errorFilePath']}")
    private String filePath;  //="C:\\Users\\prajjwal\\Documents\\errorReports.csv";

    @Override
    public Employee mapFieldSet(FieldSet fieldSet) throws BindException {
        final Employee employee = new Employee();

        employee.setEmployeeId(fieldSet.readLong("employeeId"));

        employee.setEmployeeName(fieldSet.readString("employeeName"));
        employee.setAge(fieldSet.readInt("age"));
        employee.setPincode(fieldSet.readInt("pincode"));

        if(fieldSet.readInt("age")==4) {
            try {
                System.out.println("errorFilePath"+filePath);
            FileWriter skipReport= new FileWriter(filePath, true);
            skipReport.append("fromRead,age is 4");
            skipReport.close();
            }
            catch(IOException e) {
                throw new RuntimeException();
            }
            throw new MyException("age is incorrect"+fieldSet.readString("age"));

        }
        return employee;
    }

}

这是我如何注入价值:

package com.diatoz.demo.rest;

import java.io.IOException;
import java.util.Date;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.diatoz.demo.service.EmployeeService;

@RestController
@RequestMapping("/api")
public class EmployeeResource {

    @Autowired
    EmployeeService employeeService;

    @Value("${errorFilePath}")
    private String errorFilePath;

    @Autowired
    Job job;

    @Autowired
    JobLauncher joblauncher;

    @GetMapping("/batch")
    public ResponseEntity<?> luanch(@RequestParam("file-path") String filePath)
            throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException,
            JobParametersInvalidException {

        return ResponseEntity.ok(joblauncher.run(job, new JobParametersBuilder().addDate("date", new Date())
                .addString("filePath", filePath).addString("errorFilePath", errorFilePath).toJobParameters()).getStatus());
    }
}

第二个问题是SkipListener未被跳过:

package com.diatoz.demo.configuration;

import java.io.FileWriter;
import java.io.IOException;

import org.springframework.batch.core.SkipListener;
import org.springframework.batch.core.annotation.OnSkipInProcess;
import org.springframework.batch.core.annotation.OnSkipInRead;
import org.springframework.batch.core.annotation.OnSkipInWrite;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.diatoz.demo.domain.Employee;

@Component
@StepScope
public class MySkipListener implements SkipListener<Employee, Employee> {

    @Value("#{jobParameters['errorFilePath']}")
    private String filePath;//="abc";

    @Override
    //@OnSkipInRead
    public void onSkipInRead(Throwable t) {
        if(t instanceof MyException) {
            MyException m= (MyException) t;
            try {
                System.out.println("called");
                FileWriter skipReport= new FileWriter(filePath, true);
                skipReport.append("fromRead,"+m.getMessage());
                skipReport.close();
            } catch (IOException e) {
                throw new MyException("IOException occured");
            }
            }
    }

    @Override
    //@OnSkipInWrite
    public void onSkipInWrite(Employee item, Throwable t) {

        if(t instanceof MyException) {
            MyException m= (MyException) t;
            try {
                System.out.println("called");
                FileWriter skipReport= new FileWriter(filePath, true);
                skipReport.append("fromWrite,"+m.getMessage());
                skipReport.close();
            } catch (IOException e) {
                throw new MyException("IOException occured");
            }
            }

    }

    @Override
    //@OnSkipInProcess
    public void onSkipInProcess(Employee item, Throwable t) {
System.out.println("innnn");
        if(t instanceof MyException) {
            MyException m= (MyException) t;
            try {
                System.out.println("called");
                FileWriter skipReport= new FileWriter(filePath, true);
                skipReport.append("fromProcess,"+m.getMessage());
                skipReport.close();
            } catch (IOException e) {
                throw new MyException("IOException occured");
            }
            }
    }


}

这里是配置文件:

package com.diatoz.demo.configuration;

import java.io.File;

import javax.sql.DataSource;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.LineMapper;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;

import com.diatoz.demo.domain.Employee;

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Bean
    @StepScope
    public FlatFileItemReader<Employee> reader(@Value ("#{jobParameters[filePath]}") String filePath) {
        return new FlatFileItemReaderBuilder<Employee>().name("EmployeeReader")
                .resource(new FileSystemResource(new File(filePath))).delimited()
                .names(new String[] { "employeeId", "employeeName", "age", "pincode"}).lineMapper(lineMapper())
                .fieldSetMapper(new BeanWrapperFieldSetMapper<Employee>() {
                    {
                        setTargetType(Employee.class);
                    }
                }).build();
    }

    @Bean
    public LineMapper<Employee> lineMapper() {

        final DefaultLineMapper<Employee> defaultLineMapper = new DefaultLineMapper<>();

        final DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();

        lineTokenizer.setDelimiter(",");
        lineTokenizer.setStrict(false);
        lineTokenizer.setNames(new String[] { "employeeId", "employeeName", "age", "pincode"});

        final EmployeeFieldSetMapper fieldSetMapper = new EmployeeFieldSetMapper();

        defaultLineMapper.setLineTokenizer(lineTokenizer);
        defaultLineMapper.setFieldSetMapper(fieldSetMapper);

        return defaultLineMapper;
    }

    @Bean
    public EmployeeProcessor employeeProcessor() {

        return new EmployeeProcessor();
    }

    @Bean
    public JdbcBatchItemWriter<Employee> writer(final DataSource dataSource) {
        return new JdbcBatchItemWriterBuilder<Employee>()
                .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
                .sql("INSERT INTO employee (employee_id, employee_name,age, pincode) VALUES (:employeeId, :employeeName ,:age, :pincode)")
                .dataSource(dataSource).build();
    }

    @Bean
    public Job importEmployeeJob(NotificationListener listener, Step step1) {

        return jobBuilderFactory.get("importEmployeeJob").incrementer(new RunIdIncrementer()).listener(listener)
                .flow(step1).end().build();
    }

    @Bean
    public Step step1(JdbcBatchItemWriter<Employee> writer) {
        return stepBuilderFactory.get("step1")
                .<Employee, Employee>chunk(10)
                .reader(reader(null)).faultTolerant().skip(MyException.class).skipLimit(Integer.MAX_VALUE).skipPolicy(new FileVerificationSkipper())
                .processor(employeeProcessor()).writer(writer)
                .listener( new MySkipListener()).build();
    }

    @Bean
    public ErrorTracker getErrorTracker() {
        return new ErrorTracker();
    }
}

[请指出我在做什么错。

更新后的EmployeeFieldSetMapper类:

package com.diatoz.demo.configuration;

import java.io.FileWriter;
import java.io.IOException;

import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;

import com.diatoz.demo.domain.Employee;

@Component
//@Scope(value = "step", proxyMode=ScopedProxyMode.TARGET_CLASS)  // using either @StepScope or this at a time, but none worked
@StepScope
public class EmployeeFieldSetMapper implements FieldSetMapper<Employee> {

    @Value("#{jobParameters['errorFilePath']}")
    private String filePath;//="C:\\Users\\prajjwal\\Documents\\errorReports.csv";

    @Override
    public Employee mapFieldSet(FieldSet fieldSet) throws BindException {
        final Employee employee = new Employee();

        employee.setEmployeeId(fieldSet.readLong("employeeId"));

        employee.setEmployeeName(fieldSet.readString("employeeName"));
        employee.setAge(fieldSet.readInt("age"));
        employee.setPincode(fieldSet.readInt("pincode"));

        if(fieldSet.readInt("age")==4) {
            try {
                System.out.println("errorFilePath"+filePath);
            FileWriter skipReport= new FileWriter(filePath, true);
            skipReport.append("fromRead,age is 4");
            skipReport.close();
            }
            catch(IOException e) {
                throw new RuntimeException();
            }
            throw new MyException("age is incorrect"+fieldSet.readString("age"));

        }
        return employee;
    }

}

并为MySkipListener声明@Bean:

@Bean
    @StepScope
    public MySkipListener myskipListener() {
        return new MySkipListener();
    }

呼叫.listener( myskipListener())

但是没有任何效果。 MySkipListener不会在跳过时调用,并且在[]中filePath为空

@Value("#{jobParameters['errorFilePath']}")
    private String filePath;

[第一个问题是当我打印Job参数“ errorPathFile”值时,它为null。包com.diatoz.demo.configuration;导入java.io.FileWriter;导入java.io.IOException; import org ....

spring-boot spring-batch batch-processing
1个回答
0
投票

您的EmployeeFieldSetMapper的范围不正确,原因是@Scope(value = "step")不正确。根据Javadoc,它应该是@Scope(value="step", proxyMode=TARGET_CLASS),请参阅https://github.com/spring-projects/spring-batch/issues/3651#issuecomment-587453328

© www.soinside.com 2019 - 2024. All rights reserved.