使用OpenCSV解析CSV转Java对象时如何实现字段类型转换
解决方案
OpenCSV支持解析过程中自动完成类型转换,不需要额外定义中间DTO,按以下步骤修改即可:
方案1:使用内置默认转换(满足绝大多数场景)
OpenCSV内置了基础数据类型的转换器,只要你将分数字段直接定义为Integer类型即可自动完成String到Integer的转换。
修正后的Student类
注意你提供的CSV每行共5个字段,原有注解的position映射错位,需同步调整:
public class Student { @CsvBindByPosition(position = 0) private String name; // 对应CSV第二个字段"S",可根据业务含义命名 @CsvBindByPosition(position = 1) private String tag; @CsvBindByPosition(position = 2) private Integer mathsScore; @CsvBindByPosition(position = 3) private Integer scienceScore; @CsvBindByPosition(position = 4) private Integer englishScore; // 此处省略getter、setter方法 }
修正后的解析代码
你的CSV使用|作为分隔符,不是默认的逗号,需要显式指定分隔符:
// 先构造指定分隔符的CSVReader CSVReader csvReader = new CSVReaderBuilder(new FileReader(csvFile)) .withSeparator('|') .build(); List<Student> studentsList = new CSVToBeanBuilder<Student>(csvReader) .withType(Student.class) .build() .parse();
方案2:自定义转换器(处理特殊场景)
如果需要处理空值、数字前后带空格、自定义默认值等特殊场景,可以自定义转换器实现更灵活的转换逻辑:
- 自定义类型转换器
import com.opencsv.bean.AbstractBeanField; import com.opencsv.exceptions.CsvConstraintViolationException; import com.opencsv.exceptions.CsvDataTypeMismatchException; public class CustomIntegerConverter extends AbstractBeanField<Integer, String> { @Override protected Integer convert(String value) throws CsvDataTypeMismatchException, CsvConstraintViolationException { // 空值处理:如果CSV对应字段为空,返回0或者null,可按需调整 if (value == null || value.trim().isEmpty()) { return null; } try { // 去除首尾空格后转Integer return Integer.parseInt(value.trim()); } catch (NumberFormatException e) { throw new CsvDataTypeMismatchException("非法数字格式:" + value); } } }
- 替换Student类的字段注解
public class Student { @CsvBindByPosition(position = 0) private String name; @CsvBindByPosition(position = 1) private String tag; @CsvCustomBindByPosition(position = 2, converter = CustomIntegerConverter.class) private Integer mathsScore; @CsvCustomBindByPosition(position = 3, converter = CustomIntegerConverter.class) private Integer scienceScore; @CsvCustomBindByPosition(position = 4, converter = CustomIntegerConverter.class) private Integer englishScore; // 此处省略getter、setter方法 }
两种方案转换完成后,Student对象的分数字段都是Integer类型,可直接用于数据库持久化,不需要额外做类型转换。
内容的提问来源于stack exchange,提问作者krishna
相关产品推荐
相关产品推荐

