问题
Am using supercsv CsvBeanWriter to write values to csv file.
sample class:
public class Employee {
private String name;
private int empId;
List<String> phoneNumbers;
}
Output I get is :
name,empId,phoneNumbers
vijay,1,"[123, 456]"
Note how the List<String> phoneNumbers
is written out in []
My Question is how do I read it back to Employee class(bean)using supercsv.
I tried using CsvBeanReader
& CsvDozerBeanReader
but not able to read the List<String>
.
Am getting illegalargument exception. Will be thankful for any pointers !
Complete Code:
public class DozerBeanReader {
public static void main(String [] args){
ICsvDozerBeanReader beanReader = null;
try {
beanReader = new CsvDozerBeanReader(new FileReader("Employee.csv"),
CsvPreference.STANDARD_PREFERENCE);
String [] header = beanReader.getHeader(true); // ignore the header
Class<?> [] hintTypes = {String.class, Integer.class, List.class};
beanReader.configureBeanMapping(Employee.class, header, hintTypes);
Employee readEmp1 = beanReader.read(Employee.class);
readEmp1.toString();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
回答1:
You're relying on the fact that your List
of phone numbers is written as a single CSV column using the List's toString()
format, e.g. [123, 456]
.
You will be getting an exception something like the following:
org.dozer.MappingException: Illegal object type
for the method 'setPhoneNumbers'.
Expected types:
java.util.List
Actual types:
java.lang.String
because Dozer has no idea how to convert the String [123, 456]
to a List
. You can do this, but you'll need to write a cell processor to convert that String back to a List
. If your phone numbers are purely numbers that shouldn't be too hard, but if your phone numbers have commas then things are going to get messy!
I'd recommend writing each phone number as a separate column - it makes it so much easier (for anyone reading your file, including you!).
All you'll need to do is use CsvDozerBeanReader and CsvDozerBeanWriter with indexed mapping.
Here's an example - the key part is the indexed mapping:
String[] fieldMapping = new String[] { "name",
"empId", "phoneNumbers[0]", "phoneNumbers[1]" };
- I've defined 2 phone number columns - if your List will have more, then just add more columns
- I could have used the fieldMapping for the header, but chose to use a more readable custom header
- You shouldn't need the hints as you've got in your question
- I've used StringReader/StringWriter just to make the example simple
Example:
// create employee to write/read
Employee employee = new Employee();
employee.setEmpId(1234);
employee.setName("Vijay");
employee.setPhoneNumbers(Arrays.asList("123", "456"));
// the CSV header
String[] header = new String[] { "name",
"empId", "phoneNumber1", "phoneNumber2" };
// the field mapping
String[] fieldMapping = new String[] { "name",
"empId", "phoneNumbers[0]", "phoneNumbers[1]" };
// write the employee
StringWriter out = new StringWriter();
ICsvDozerBeanWriter writer =
new CsvDozerBeanWriter(out,
CsvPreference.STANDARD_PREFERENCE);
writer.configureBeanMapping(Employee.class, fieldMapping);
writer.writeHeader(header);
writer.write(employee);
writer.flush();
// read the employee
ICsvDozerBeanReader reader =
new CsvDozerBeanReader(new StringReader(out.toString()),
CsvPreference.STANDARD_PREFERENCE);
reader.configureBeanMapping(Employee.class, fieldMapping);
reader.getHeader(true); // ignore header
Employee e = reader.read(Employee.class);
System.out.println(e);
Assuming you've written the toString()
method, this should print
Employee [name=Vijay, empId=1234, phoneNumbers=[123, 456]]
来源:https://stackoverflow.com/questions/21145412/how-to-write-liststring-to-csv-file-read-it-back-using-supercsv