I am attempting to use OpenCSV to process my CSV file delimited by semicolons, and I've written my representative bean's fields with the relevant annotations—with @CsvBindAndSplitByName
—and it appears to fail on a list of Double
s but not with a list of String
s. Why is this?
My bean:
import com.opencsv.bean.CsvBindAndSplitByName;
import com.opencsv.bean.CsvBindByName;
import java.util.List;
public class TestBean {
@CsvBindByName(column = "name", required = true)
private String name;
@CsvBindAndSplitByName(elementType = String.class, column = "desc", writeDelimiter = ",")
private List<String> descriptions;
@CsvBindAndSplitByName(elementType = Double.class, column = "values", writeDelimiter = ",")
private List<Double> values;
}
My data(test.csv
):
name; desc; values
potato; langez, canou, passen; 3.55, 2.76, 1.92
And reading the file and processing it:
import com.opencsv.bean.CsvToBeanBuilder;
import java.io.FileNotFoundException;
import java.util.List;
import java.io.FileReader;
public class TestBeanReader {
public static void main(String[] args) throws FileNotFoundException {
List<TestBean> locations = new CsvToBeanBuilder<TestBean>(new FileReader("test.csv")).withSeparator(';').withType(TestBean.class).build().parse();
}
}
Output:
Exception in thread "pool-1-thread-1" Exception in thread "main" java.lang.RuntimeException: com.opencsv.exceptions.CsvDataTypeMismatchException: Conversion of 3.55, to java.lang.Double failed.
at com.opencsv.bean.util.OpencsvUtils.handleException(OpencsvUtils.java:128)
at com.opencsv.bean.concurrent.ProcessCsvLine.run(ProcessCsvLine.java:108)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: com.opencsv.exceptions.CsvDataTypeMismatchException: Conversion of 3.55, to java.lang.Double failed.
at com.opencsv.bean.ConverterPrimitiveTypes.convertToRead(ConverterPrimitiveTypes.java:128)
at com.opencsv.bean.BeanFieldSplit.convert(BeanFieldSplit.java:203)
at com.opencsv.bean.AbstractBeanField.setFieldValue(AbstractBeanField.java:182)
at com.opencsv.bean.AbstractMappingStrategy.setFieldValue(AbstractMappingStrategy.java:631)
at com.opencsv.bean.AbstractMappingStrategy.populateNewBean(AbstractMappingStrategy.java:334)
at com.opencsv.bean.concurrent.ProcessCsvLine.processLine(ProcessCsvLine.java:131)
at com.opencsv.bean.concurrent.ProcessCsvLine.run(ProcessCsvLine.java:87)
... 3 more
Caused by: org.apache.commons.beanutils.ConversionException: Error converting from 'String' to 'Double' For input string: "3.55,"
at org.apache.commons.beanutils.converters.AbstractConverter.handleError(AbstractConverter.java:282)
at org.apache.commons.beanutils.converters.AbstractConverter.convert(AbstractConverter.java:177)
at org.apache.commons.beanutils.converters.ConverterFacade.convert(ConverterFacade.java:61)
at org.apache.commons.beanutils.ConvertUtilsBean.convert(ConvertUtilsBean.java:491)
at com.opencsv.bean.ConverterPrimitiveTypes.convertToRead(ConverterPrimitiveTypes.java:118)
... 9 more
CodePudding user response:
From what I can see in TestBean class, you use writeDelimiter = ","
to separate individual columns. This works, but does not exclude the delimiter (',' in your case), so it tries to parse "3.55," instead of "3.55". The same names for earlier strings in your list are "langez,", "canou,", "passen" instead of "langez", "canou", "passen". I suggest instead to use "splitOn =", "" which excludes commas.
@CsvBindAndSplitByName(elementType = Double.class, column = "values", splitOn = ",")
private List<Double> values;