使用Spring Batch导入CSV到MySQL遇FlatFileParseException错误
解决Spring Batch CSV解析的IncorrectTokenCountException错误
错误原因
触发IncorrectTokenCountException的核心原因是DelimitedLineTokenizer的配置冲突:
- 通过
setNames定义了24个字段名,Spring Batch据此预期每行解析出24个token - 同时用
setIncludedFields指定只提取7列,实际解析后仅得到7个token - 预期数量与实际数量不匹配,导致报错
解决方案
方案一:匹配字段名数量与提取列数
调整setNames的字段名数组,仅保留需要映射的7个字段,与setIncludedFields指定的列数完全一致:
private LineMapper<Player> getLineMapper() { DefaultLineMapper<Player> lineMapper = new DefaultLineMapper<>(); DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer(); // 字段名数量与includedFields的列数一一对应 lineTokenizer.setNames(new String[] {"playerID", "birthYear", "birthCity", "nameFirst", "nameLast", "retroID", "bbrefID"}); lineTokenizer.setIncludedFields(new int[] {0, 1, 6, 13, 14, 22, 23}); BeanWrapperFieldSetMapper<Player> fieldSetMapper = new BeanWrapperFieldSetMapper<>(); fieldSetMapper.setTargetType(Player.class); lineMapper.setLineTokenizer(lineTokenizer); lineMapper.setFieldSetMapper(fieldSetMapper); return lineMapper; }
方案二:利用空字段名自动跳过列
如果希望保留原setNames的写法(用空字符串标记跳过的列),需移除setIncludedFields配置,DelimitedLineTokenizer会自动忽略字段名为空的列:
private LineMapper<Player> getLineMapper() { DefaultLineMapper<Player> lineMapper = new DefaultLineMapper<>(); DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer(); // 空字符串对应的列会被自动跳过 lineTokenizer.setNames(new String[] {"playerID","birthYear","","","","","birthCity","","","","","","","nameFirst","nameLast","","","","","","","","retroID","bbrefID"}); // 移除setIncludedFields配置 BeanWrapperFieldSetMapper<Player> fieldSetMapper = new BeanWrapperFieldSetMapper<>(); fieldSetMapper.setTargetType(Player.class); lineMapper.setLineTokenizer(lineTokenizer); lineMapper.setFieldSetMapper(fieldSetMapper); return lineMapper; }
额外验证
从错误日志的input内容来看,People2.csv的第二行(已跳过第一行表头)确实包含24个逗号分隔的列,符合配置要求,无需调整文件内容。
内容的提问来源于stack exchange,提问作者Aryan Singh
相关产品推荐
相关产品推荐

