java - Spring Batch ItemReader 在第一行获取 NullPointerException
问题描述
当我尝试读取我的 csv 文件时,我遇到了 Spring batch 的这个问题。
我必须阅读具有如下结构的CSV:
valueHeader;valueHeader;valueHeader;valueHeader;valueHeader;valueHeader
conventValue;conventValue;conventValue;conventValue;conventValue
conventValue;conventValue;conventValue;conventValue;conventValue
conventValue;conventValue;conventValue;conventValue;conventValue
valueFooter;valueFooter;valueFooter;valueFooter;valueFooter;valueFooter
我有一个MultiResourceItemReader,它委托 String 类型的FlatFileItemReader,以便在之后执行的自定义项处理器中轻松将此行映射到我的自定义 DTO。
在我的 Tasklet 中,我像这样注入了 MultiResourceItemReader bean:
@Autowired
private MultiResourceItemReader<String> resourceItemReader;
然后我这样称呼它(设置资源和上下文):
resourceItemReader.setStrict(Boolean.FALSE);
resourceItemReader.setResources(resources);
resourceItemReader.open(context.getStepContext().getStepExecution().getExecutionContext());
String currentContent = resourceItemReader.read();
while(currentContent != null) {
linesReaded.add(currentContent);
currentContent = resourceItemReader.read();
}
But I am getting a **NullPointerException** in the first Line and I don't know why:
20190705 19:53:30.041 INFO com.mycomp.mycustomp.tasklet.MyCustomTasklet [[ # ]] - [MyCustomTasklet:EXECUTE]
20190705 19:53:41.560 ERROR org.springframework.batch.core.step.AbstractStep [[ # ]] - Encountered an error executing step processRebateASLIStep in job MyProyectJob
org.springframework.batch.item.file.FlatFileParseException: Parsing error at line: 1 in resource=[file [C:\Pruebas\MyProyectJob\destino\MyFile-100-20151130143000-000001.csv]], input=[HEADER;PEP;FacteTRY;100; 20151130143000;000125;100000000000000000000000000000000025874]
at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:183)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:88)
at org.springframework.batch.item.file.MultiResourceItemReader.readFromDelegate(MultiResourceItemReader.java:140)
at org.springframework.batch.item.file.MultiResourceItemReader.readNextItem(MultiResourceItemReader.java:119)
at org.springframework.batch.item.file.MultiResourceItemReader.read(MultiResourceItemReader.java:108)
....
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Caused by: java.lang.NullPointerException: null
at org.springframework.batch.item.file.mapping.DefaultLineMapper.mapLine(DefaultLineMapper.java:43)
at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:180)
... 59 common frames omitted
我也会附上我的 readerItems bean:
@Bean
MultiResourceItemReader<String> resourceItemReader(FlatFileItemReader<String> flatFileItemReader){
MultiResourceItemReader<String> resourceItemReader = new MultiResourceItemReader<>();
resourceItemReader.setDelegate(flatFileItemReader);
resourceItemReader.setStrict(false);
return resourceItemReader;
}
@Bean
FlatFileItemReader<String> flatFileItemReader() {
FlatFileItemReader<String> reader = new FlatFileItemReader<String>();
reader.setStrict(false);
reader.setLineMapper(new DefaultLineMapper<String>() {
{
//Setea los valores en la clase indicada
setFieldSetMapper(new FieldSetMapper<String>() {
@Override
public String mapFieldSet(FieldSet fieldSet) throws BindException {
String[] values = fieldSet.getValues();
return String.join(";", values);
}
});
}
});
return reader;
}
解决方案
您没有在LineMapper
. 添加方法如下:
reader.setLineMapper(new DefaultLineMapper<String>() {
{
//Setea los valores en la clase indicada
setFieldSetMapper(new FieldSetMapper<String>() {
@Override
public String mapFieldSet(FieldSet fieldSet) throws BindException {
String[] values = fieldSet.getValues();
return String.join(";", values);
}
});
setLineTokenizer(new DelimitedLineTokenizer(";"));
}
});
由于其流畅的 API,我建议使用FlatFileItemReaderBuilder
更直观的方法。这是一个例子:
@Bean
public FlatFileItemReader<Pojo> flatFileItemReader() {
return new FlatFileItemReaderBuilder<Pojo>()
.name("itemReader")
.resource(new FileSystemResource("/path/to/flat/file"))
.targetType(Pojo.class)
.delimited()
.delimiter(";")
.names("column1", "column2")
.build();
}
希望这可以帮助。
推荐阅读
- angularjs - PDFJS:文本层渲染两次
- git - 无法通过 Git Bash 将 Origin Master 推送到 GitHub
- python - 如何在 python 中使用 plotly 制作混合统计子图?
- excel - 如何使用 vba Excel 修复“运行时错误 91:“对象变量或未设置块变量”?
- python - 为什么你分配的初始值 p0 会在很大程度上影响拟合结果
- c# - C#:在文本框中查询多列
- oracle - 使用虚拟列的 Oracle 自动 LIST 分区不允许子表上的 REFERENCE 分区
- node.js - 如何在显示数据之前处理需要令牌的nodejs中的多个传入请求
- typescript - 泛型函数类型别名
- android - 本地数据持久化后如何处理 API 中的更新数据?