In my CSV I have inconsistent data so I have to log the error while iterating record and want to create a list of POJO of valid CSV records. I am using OpenCsv to process the CSV file. I have added try-catch block to log the error if there is any but at while(iterator.hasNext()) there is the exception/error as next record has some incorrect formatted data.
So how to log the error and continue to process the next record?
List<UserProvisioning> list = new ArrayList<>();
CsvToBean<UserProvisioning> beans = new CsvToBeanBuilder<UserProvisioning>(
new FileReader(file.getAbsolutePath())).withType(UserProvisioning.class)
.withIgnoreQuotations(true).build();
Iterator<UserProvisioning> iterator = beans.iterator();
while (iterator.hasNext()) {
try {
UserProvisioning userProvisioning = (UserProvisioning) iterator.next();
System.out.println(userProvisioning.getFIRST_NAME());
list.add(userProvisioning);
} catch (Exception e) {
// TODO Auto-generated catch block
logger.error("Error occured...)
}
}
If I use .withThrowExceptions(false) I can process all valid records but not able to log the error.
Error
java.lang.RuntimeException: com.opencsv.exceptions.CsvRequiredFieldEmptyException: Number of data fields does not match number of headers.
at com.opencsv.bean.concurrent.ProcessCsvLine.run(ProcessCsvLine.java:101)
at com.opencsv.bean.CsvToBean$CsvToBeanIterator.readLineWithPossibleError(CsvToBean.java:551)
at com.opencsv.bean.CsvToBean$CsvToBeanIterator.readSingleLine(CsvToBean.java:571)
at com.opencsv.bean.CsvToBean$CsvToBeanIterator.next(CsvToBean.java:591)
at com.apds.partner.nycdoc.main.NycDocApplication.main(NycDocApplication.java:90)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: com.opencsv.exceptions.CsvRequiredFieldEmptyException: Number of data fields does not match number of headers.
at com.opencsv.bean.HeaderColumnNameMappingStrategy.verifyLineLength(HeaderColumnNameMappingStrategy.java:110)
at com.opencsv.bean.AbstractMappingStrategy.populateNewBean(AbstractMappingStrategy.java:313)
at com.opencsv.bean.concurrent.ProcessCsvLine.processLine(ProcessCsvLine.java:132)
at com.opencsv.bean.concurrent.ProcessCsvLine.run(ProcessCsvLine.java:85)
... 9 more
How to create a list of valid csv records by logging the error of invalid record using OpenCsv?
As per my understanding iterator.hasNext() tries to check whether next element is present or not by mapping csv record column to POJO fields and as there is invalid data in csv record headers count do not matches record files hence error java.lang.RuntimeException: com.opencsv.exceptions.CsvRequiredFieldEmptyException: Number of data fields does not match number of headers.
EDIT
OpenCSV version 4.6
Sample Records:
ID1,ID2,FIRST_NAME,LAST_NAME,BIRTH_DATE,HA1,HA2,TYPE,STATUS,DT,LEVEL
3491905454,04572538R,L,L,1964-08-01,RNDC,M4SL,GP ,DEP,,
3491901894,04353902J,TO,TO,1962-10-20,AMKC,QUAD-L3,GP ,DE,,
3491903493,01940960Y,JAM"ES,TO,1985-03-12,GRVC,13A,PS ,DPV,,
8951900652,08661334Z,"ROT,TEST",RODRIGUEZ,1971-09-17,AMKC,1 TOP,GP ,DE,,
4411801431,02661015Y,CET,TEC,1964-06-21,RNDC,M4NU,GP ,DE,,
9801900155,06467584H,RAT,BAT,1969-12-01,GRVC,8A,GP ,DE,,GSL3
4th and 5th lines has inconsistant data
CsvToBeanBuilder
.withThrowExceptions(false)
to
ignore runtime exceptionsgetCapturedExceptions()
to get all exceptions that
would have been thrown during the import, but were suppressedCsvException
array (after parsing) and log
exceptionsSee the code snippet below:
final CsvToBean<UserProvisioning> beans =
new CsvToBeanBuilder<UserProvisioning>(new FileReader("c:\\test.csv"))
.withType(UserProvisioning.class)
.withIgnoreQuotations(true)
.withThrowExceptions(false) //1
.build();
final List<UserProvisioning> users = beans.parse();//2
users.stream().forEach((user) -> {
logger.info("Parsed data:" + user.toString());
});
beans.getCapturedExceptions().stream().forEach((exception) -> { //3
logger.error("Inconsistent data:" +
String.join("", exception.getLine()), exception);//4
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With