Java 在stepExecutionContext中存储行号并访问它

Java 在stepExecutionContext中存储行号并访问它,java,spring,spring-batch,Java,Spring,Spring Batch,我试图通过将csv文件中每个项目的行号存储在executionContext中来跟踪它。Reader是一个FlatFileItemReader,带有经过修改的lineMapper。这是它的代码: public class MyLineMapper<T> implements LineMapper<T>, InitializingBean { private LineTokenizer tokenizer; private FieldSetMapper<T>

我试图通过将csv文件中每个项目的行号存储在executionContext中来跟踪它。Reader是一个FlatFileItemReader,带有经过修改的lineMapper。这是它的代码:

public class MyLineMapper<T> implements LineMapper<T>, InitializingBean {

private LineTokenizer tokenizer;

private FieldSetMapper<T> fieldSetMapper;

public T mapLine(String line, int lineNumber) throws Exception {
    try{

        ExecutionContext value = new ExecutionContext();
        value.putInt("name", lineNumber);


        return fieldSetMapper.mapFieldSet(tokenizer.tokenize(line));
    }
    catch(Exception ex){
        throw new FlatFileParseException("Parsing error at line: " + lineNumber + 
                ", input=[" + line + "]", ex, line, lineNumber); 
    }
}

public void setLineTokenizer(LineTokenizer tokenizer) {
    this.tokenizer = tokenizer;
}

public void setFieldSetMapper(FieldSetMapper<T> fieldSetMapper) {
    this.fieldSetMapper = fieldSetMapper;
}

public void afterPropertiesSet() {
    Assert.notNull(tokenizer, "The LineTokenizer must be set");
    Assert.notNull(fieldSetMapper, "The FieldSetMapper must be set");
}

}

让您的
MyLineMapper
实现并在
StepExecutionListener
中绑定当前步骤执行上下文,而不是创建新的步骤执行上下文

public class MyLineMapper<T> implements LineMapper<T>, InitializingBean, StepExecutionContext {
  ExecutionContext stepExecution;

  public void beforeStep(ExecutionContext stepExecution) { this.stepExecution = stepExecution;}

  public T mapLine(String line, int lineNumber) throws Exception {
    this.stepExecution.putInt("name", lineNumber);
    // rest of your code..
  }
}
公共类MyLineMapper实现了LineMapper、InitializingBean、StepExecutionContext{ 执行上下文逐步执行; public void beforeStep(ExecutionContext stepExecution){this.stepExecution=stepExecution;} 公共T映射行(字符串行,整数行号)引发异常{ this.stepExecution.putInt(“名称”,行号); //代码的其余部分。。 } }
你也可以看看,;不是完全一样,但(可能)对您的需要有用。

尝试在步骤执行中更新ExitStatus中的计数:

@Override
    public ExitStatus afterStep(StepExecution arg0) {
}

谢谢@bellabax,成功了。我必须做一些细微的更改:将stepExecution设置为stepExecution类型,然后使用getExecutionContext().putInt()添加行号。最后在步骤1a中添加MyLineMapper作为侦听器出现了问题:虽然ExecutionContext是使用当前行从MyLineMapper更新的,但处理器仅保留第一个值,这可能是由于步骤作用域的缘故。是否有方法更新处理器中的ExecutionContext?在存储行号的地方使用int[]或List或自定义T对象(以与ItemCountAware intf类似的方式)
10:34:48.146 [main] DEBUG o.s.b.core.step.tasklet.TaskletStep - Rollback for RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.itemProcessor' defined in class path resource [spring/batch/jobs/job-hello-world.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'null' to required type 'int' for property 'field'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [null] to required type [int] for property 'field': PropertyEditor [org.springframework.beans.propertyeditors.CustomNumberEditor] returned
inappropriate value of type [null]
10:34:48.155 [main] DEBUG o.s.t.support.TransactionTemplate - Initiating transaction rollback on application exception
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.itemProcessor' defined in class path resource [spring/batch/jobs/job-hello-world.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'null' to required type 'int' for property 'field'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [null] to required type [int] for
property 'field': PropertyEditor [org.springframework.beans.propertyeditors.CustomNumberEditor] returned inappropriate value of type [null]
public class MyLineMapper<T> implements LineMapper<T>, InitializingBean, StepExecutionContext {
  ExecutionContext stepExecution;

  public void beforeStep(ExecutionContext stepExecution) { this.stepExecution = stepExecution;}

  public T mapLine(String line, int lineNumber) throws Exception {
    this.stepExecution.putInt("name", lineNumber);
    // rest of your code..
  }
}
@Override
    public ExitStatus afterStep(StepExecution arg0) {
}