Spring Batch读取CSV转Tarification对象时解析错误求助
问题:Spring Batch读取CSV转Tarification对象时解析失败
尝试读取CSV文件并将数据转换为Tarification对象,但始终遇到解析错误。已尝试移除引号、修改分隔符、测试其他数据、检查字段名等操作,问题仍未解决。
Tarification类
public class Tarification { private String id; private String age; private Double tauxApplicable; private String typeReseau; public Tarification(String id, String age, Double tauxApplicable, String typeReseau) { this.id = id; this.age = age; this.tauxApplicable = tauxApplicable; this.typeReseau = typeReseau; } }
CSV文件内容示例
"816473dd-a200-4d05-9b5f-b77e7acd0bcf;50;5.1686956;01" "f8fa6cbd-6bc9-4531-973f-cb6d1b10ae38;51;5.30325005;01" "2a44e8f0-4eef-471c-a36a-cd5451e0bf91;52;5.44481506;01" "02f26874-b585-41d6-b853-c9a6bb30c7e3;53;5.59391256;01"
FlatFileItemReader实现代码
public FlatFileItemReader<Tarification> reader(String filePath) throws IOException { LOGGER.info("----- Nouveau FlatFileItemReader avec input {} -----", filePath); // Tentative de résolution du fichier d'entrée sur Filesystem et sur Classpath par facilité Resource inputResource; if(new FileSystemResource(filePath).exists()) { inputResource = new FileSystemResource(filePath); } else { // Utile pour les TU inputResource = new ClassPathResource(filePath); } // Controle de disponibilité du fichier, son absence lèvera une exception en runtime if(!inputResource.exists()) { throw new IOException("Fichier non trouvé avec " + filePath); } BeanWrapperFieldSetMapper<Tarification> beanWrapperFieldSetMapper = new BeanWrapperFieldSetMapper<>(); beanWrapperFieldSetMapper.setTargetType(Tarification.class); return new FlatFileItemReaderBuilder<Tarification>() .name("tarificationItemReader") .resource(inputResource) .delimited() .delimiter(";") .names("id", "age", "tauxApplicable", "typeReseau") .fieldSetMapper(beanWrapperFieldSetMapper) .build(); }
错误信息
org.springframework.batch.item.file.FlatFileParseException: Parsing error at line: 1 in resource=[class path resource [mmaserenite_donnees_tarif_agenceMMACAP.csv]], input=[816473dd-a200-4d05-9b5f-b77e7acd0bcf;50;5.1686956;01]
解决方案
问题源于CSV格式与Spring Batch配置不匹配,以及Tarification类缺少必要的构造方法:
- CSV行被整体包裹在引号中:Spring Batch默认不会识别这种格式,会把整行当成单个字段,无法按
;分割为4个目标字段,导致解析失败。 - 缺少无参构造方法:
BeanWrapperFieldSetMapper需要目标类提供无参构造才能完成对象映射,当前类只有带参构造,会导致映射失败。
修改步骤:
1. 配置Spring Batch处理带引号的CSV行
在FlatFileItemReaderBuilder中添加引号字符配置:
return new FlatFileItemReaderBuilder<Tarification>() .name("tarificationItemReader") .resource(inputResource) .delimited() .delimiter(";") .names("id", "age", "tauxApplicable", "typeReseau") .quoteCharacter('"') // 指定引号字符,让框架自动处理行首尾的引号 .fieldSetMapper(beanWrapperFieldSetMapper) .build();
2. 为Tarification类添加无参构造及Getter/Setter
public class Tarification { private String id; private String age; private Double tauxApplicable; private String typeReseau; // 添加无参构造方法 public Tarification() {} public Tarification(String id, String age, Double tauxApplicable, String typeReseau) { this.id = id; this.age = age; this.tauxApplicable = tauxApplicable; this.typeReseau = typeReseau; } // 添加Getter/Setter,供BeanWrapperFieldSetMapper访问私有字段 public String getId() { return id; } public void setId(String id) { this.id = id; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public Double getTauxApplicable() { return tauxApplicable; } public void setTauxApplicable(Double tauxApplicable) { this.tauxApplicable = tauxApplicable; } public String getTypeReseau() { return typeReseau; } public void setTypeReseau(String typeReseau) { this.typeReseau = typeReseau; } }
补充说明
如果CSV的引号属于多余格式,也可以预处理去除每行首尾的引号,但通过quoteCharacter配置是Spring Batch的标准处理方式。同时确保字段名与类属性名完全匹配(当前配置已满足匹配要求)。
内容的提问来源于stack exchange,提问作者goujon
相关产品推荐
相关产品推荐

