Java 在stepExecutionContext中存储行号并访问它
我试图通过将csv文件中每个项目的行号存储在executionContext中来跟踪它。Reader是一个FlatFileItemReader,带有经过修改的lineMapper。这是它的代码: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>
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) {
}