我正在使用 openCsv 库,因为它非常易于使用,并且我获得了所有必要的功能。但现在我需要使用一些自定义逻辑,除了检查正确的类型、列和其他常见的东西。我有一个 csv,其中包含 firstName
、secondName
、firstSalary
、lastSalary
等列。我想在解析过程中检查 firstDayOfWork
是否小于 lastDayOfWork
,如果为 false,则添加一个新的 csvException 。所以,如果现在我正在解析文件
firstName,secondName,firstSalary,lastSalary
John, Doe, testtext, 5000
Alice, , 100, 5000
Harry, Smith, 400, 200
并处理 csvExcpetions 列表,我可以获得像
这样的解析结果Number of mistakes: 2
Line 1: Conversion of testtext to java.lang.Integer failed.
Line 2: Field 'secondName' is mandatory but no value was provided.
我想要类似的东西
Number of mistakes: 3
Line 1: Conversion of testtext to java.lang.Integer failed.
Line 2: Field 'secondName' is mandatory but no value was provided.
Line 3: firstSalary cannot be more than lastSalary
或者一些自定义解析逻辑,例如检查某个字段是否捕获正则表达式、两个字段同时大于 0 等。
我可以首先将其解析并转换为bean,然后在第二个周期检查我的bean是否符合这些规则,但是可能会有很多行,并且需要更长的时间,所以,我想在一个过程中检查它。
我可以通过openCsv获取它吗?如果是的话,怎么办?如果不是,我还可以使用什么其他工具? 谢谢。
最佳答案
基于How to create a list of valid CSV records by logging the error of invalid record using OpenCsv? ,您可以:
,而不是在 setter 中抛出 IllegalArgumentException- 创建一个 BeanVerifier 以在创建后验证整个 bean;
- 出错时抛出
CsvConstraintViolationException
; - 将
.withThrowExceptions(false)
添加到CsvToBeanBuilder
; - 调用
getCapturedExceptions()
来收集验证错误。
此解决方案的优点是您可以根据需要收集 CSV 异常(exception)列表:
示例
final CsvToBean<EmployeeBean> csvToBean =
new CsvToBeanBuilder<EmployeeBean>(new FileReader("c:\\test.csv"))
.withType(EmployeeBean.class)
.withVerifier(new EmployeeSalaryVerifier())
.withThrowExceptions(false)
.build();
final List<EmployeeBeans> employees = csvToBean.parse();
List<CsvException> exceptions = parser.getCapturedExceptions();
// logging number of mistakes and, for each exception, its line number and message
logger.error("Number of Mistakes: {}", exceptions.size());
employees.getCapturedExceptions().stream().forEach(ex ->
logger.error("Line {}: {}", ex.getLineNumber(), ex.getMessage(), ex));
EmployeeBean
public class EmployeeBean {
@CsvBindByName(column = "First Name", required = true)
private String firstName;
@CsvBindByName(column = "Last Name", required = true)
private String lastName;
@CsvBindByName(column = "First Salary" required = true)
private Long firstSalary;
@CsvBindByName(column = "Last Salary")
private Long lastSalary;
// regular getters and setters, no validation here
}
BeanVerifier
public class EmployeeSalaryVerifier implements BeanVerifier<EmployeeBean> {
@Override
public boolean verifyBean(Employee bean) throws CsvConstraintViolationException {
// check salary
if (bean.getLastSalary() != null && bean.getFirstSalary().compareTo(bean.getLastSalary()) > 0) {
throw new CsvConstraintViolationException("First Salary cannot be greater than Last Salary.");
}
return true;
}
关于java - Opencsv解析中的自定义逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48691164/