如何使用 Univocity 例程验证 CSV headers?
How to validate CSV headers using Univocity routines?
我在遍历 Java bean 时将 Univocity CSV 解析器与例程一起使用。有没有办法验证 CSV header?当我编辑 CSV 并添加无效 header 时,它只是插入给定的 bean null 而没有任何错误。
型号class:
public class Customer {
@Format(formats ="yyyy-MM-dd")
@Parsed(field="C_DAY")
private Date day;
@Parsed(field="C_ID")
private Long id;
@Parsed(field="C_TYPE")
private String type;
@Format(formats ="yyyy-MM-dd")
@Parsed(field="C_ORIGIN_DATE")
private Date originDate;
@Format(formats ="yyyy-MM-dd")
@Parsed(field="C_REL_DATE")
private Date relDate;
@Parsed(field="C_LEGAL_ID")
private String legalId;
@Parsed(field="C_NAME")
private String name;}
解析器:
@Autowired
private CustomerDAO dao;
public void parse(File file) throws IOException, SQLException, CustomerValidationException, ParseException {
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.getFormat().setLineSeparator("\n");
parserSettings.setHeaderExtractionEnabled(false);
CsvRoutines routines = new CsvRoutines(parserSettings);
List<Customer> customers = new ArrayList<>();
java.util.Date stamp = getTimestamp(file);
dao.checkTimestampDate(stamp);
for (Customer customer : routines.iterate(Customer.class, file, "UTF-8")) {
validateFileDateWithFileName(stamp, customer.getDay());
validateCustomer(customer);
customers.add(customer);
}
dao.save(customers);
}
这里是图书馆的作者。 BeanListProcessor
有一个 strictHeaderValidationEnabled
属性 您可以设置为 true
以确保您的 class 中的所有 headers 都存在于输入中。
在这种情况下,您不能使用 CsvRoutines
,因为 class 实现了使用其内部行处理器的便捷方法,因此您的方法将被忽略。试试这个代码:
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.getFormat().setLineSeparator("\n");
final List<Customer> customers = new ArrayList<>();
final java.util.Date stamp = getTimestamp(file);
dao.checkTimestampDate(stamp);
parserSettings.setProcessor(new BeanProcessor<Customer>() {
@Override
public void beanProcessed(Customer customer, ParsingContext context) {
validateFileDateWithFileName(stamp, customer.getDay());
validateCustomer(customer);
customers.add(customer);
}
});
new CsvParser(parserSettings).parse(file, "UTF-8");
dao.save(customers);
希望对您有所帮助。
基于 Jeronimo Backes 的回答。
如果您在 bean 上有 @Header
注释或知道确切的 headers 但仍然需要 setHeaderExtractionEnabled(true)
:
public <T> List<T> parse(File file, Class<T> beanType, char delimiter, Charset charset) {
String[] headers = beanType.getDeclaredAnnotation(Headers.class).sequence(); // or other source
CsvParserSettings parserSettings = Csv.parseRfc4180(); // or some other
parserSettings.detectFormatAutomatically(delimiter);
parserSettings.setHeaderExtractionEnabled(true);
// initialize new processor (stateful, should not be reused! See implementation of parseAll)
BeanListProcessor<T> processor= new BeanListProcessor<>();
processor.setStrictHeaderValidationEnabled(true);
parserSettings.setProcessor(processor);
CsvParser csvParser = new CsvParser(parserSettings);
csvParser.parse(file, charset);
// header validation
String[] headersParsed = processor.getHeaders();
if (!Arrays.equals(headers, headersParsed)) {
String message = String.format("Header validation failed. Expected: %s, but was: %s",
Arrays.toString(headers), Arrays.toString(headersParsed));
throw new DataProcessingException(message);
}
return beanListProcessor.getBeans();
}
我在遍历 Java bean 时将 Univocity CSV 解析器与例程一起使用。有没有办法验证 CSV header?当我编辑 CSV 并添加无效 header 时,它只是插入给定的 bean null 而没有任何错误。
型号class:
public class Customer {
@Format(formats ="yyyy-MM-dd")
@Parsed(field="C_DAY")
private Date day;
@Parsed(field="C_ID")
private Long id;
@Parsed(field="C_TYPE")
private String type;
@Format(formats ="yyyy-MM-dd")
@Parsed(field="C_ORIGIN_DATE")
private Date originDate;
@Format(formats ="yyyy-MM-dd")
@Parsed(field="C_REL_DATE")
private Date relDate;
@Parsed(field="C_LEGAL_ID")
private String legalId;
@Parsed(field="C_NAME")
private String name;}
解析器:
@Autowired
private CustomerDAO dao;
public void parse(File file) throws IOException, SQLException, CustomerValidationException, ParseException {
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.getFormat().setLineSeparator("\n");
parserSettings.setHeaderExtractionEnabled(false);
CsvRoutines routines = new CsvRoutines(parserSettings);
List<Customer> customers = new ArrayList<>();
java.util.Date stamp = getTimestamp(file);
dao.checkTimestampDate(stamp);
for (Customer customer : routines.iterate(Customer.class, file, "UTF-8")) {
validateFileDateWithFileName(stamp, customer.getDay());
validateCustomer(customer);
customers.add(customer);
}
dao.save(customers);
}
这里是图书馆的作者。 BeanListProcessor
有一个 strictHeaderValidationEnabled
属性 您可以设置为 true
以确保您的 class 中的所有 headers 都存在于输入中。
在这种情况下,您不能使用 CsvRoutines
,因为 class 实现了使用其内部行处理器的便捷方法,因此您的方法将被忽略。试试这个代码:
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.getFormat().setLineSeparator("\n");
final List<Customer> customers = new ArrayList<>();
final java.util.Date stamp = getTimestamp(file);
dao.checkTimestampDate(stamp);
parserSettings.setProcessor(new BeanProcessor<Customer>() {
@Override
public void beanProcessed(Customer customer, ParsingContext context) {
validateFileDateWithFileName(stamp, customer.getDay());
validateCustomer(customer);
customers.add(customer);
}
});
new CsvParser(parserSettings).parse(file, "UTF-8");
dao.save(customers);
希望对您有所帮助。
基于 Jeronimo Backes 的回答。
如果您在 bean 上有 @Header
注释或知道确切的 headers 但仍然需要 setHeaderExtractionEnabled(true)
:
public <T> List<T> parse(File file, Class<T> beanType, char delimiter, Charset charset) {
String[] headers = beanType.getDeclaredAnnotation(Headers.class).sequence(); // or other source
CsvParserSettings parserSettings = Csv.parseRfc4180(); // or some other
parserSettings.detectFormatAutomatically(delimiter);
parserSettings.setHeaderExtractionEnabled(true);
// initialize new processor (stateful, should not be reused! See implementation of parseAll)
BeanListProcessor<T> processor= new BeanListProcessor<>();
processor.setStrictHeaderValidationEnabled(true);
parserSettings.setProcessor(processor);
CsvParser csvParser = new CsvParser(parserSettings);
csvParser.parse(file, charset);
// header validation
String[] headersParsed = processor.getHeaders();
if (!Arrays.equals(headers, headersParsed)) {
String message = String.format("Header validation failed. Expected: %s, but was: %s",
Arrays.toString(headers), Arrays.toString(headersParsed));
throw new DataProcessingException(message);
}
return beanListProcessor.getBeans();
}