数组的 Jackson-CSV 架构
Jackson-CSV schema for array
我有 CSV
个文件需要解析。此文件的架构如下:
name, contacts - where contacts are many strings for each person where
the number of this contact columns is not regular.
例如:
john, john@wick.com, 123 123 123, fb/john.wick
mike, 123 0303 11
dave,
我正在尝试用 Jacskon CSV
为我的 bean 创建一个 CsvSchema
:
public class Person {
private String name;
private String[] contacts;
}
通过创建自定义架构:
CsvSchema schema = CsvSchema.builder()
.addColumn("name")
.addArrayColumn("contacts", ",")
.build();
但我得到这个:
com.fasterxml.jackson.dataformat.csv.CsvMappingException: Too many entries: expected at most 2
如何用Jackson CSV
解决这样的问题?
Java
代码:
CsvMapper mapper = new CsvMapper();
CsvSchema schema = CsvSchema.builder()
.addColumn("name")
.addArrayColumn("contacts", ",")
.build();
MappingIterator<Person> it = mapper.readerFor(Person.class).with(schema)
.readValues(csvString);
List<Person> all = it.readAll();
您可以使用 CsvParser.Feature.WRAP_AS_ARRAY 功能并将整行读取为 List<String>
。在构造函数中,您可以将 List
转换为 Person
对象。请参阅以下示例:
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvParser;
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
public class CsvApp {
public static void main(String[] args) throws Exception {
File csvFile = new File("./resource/test.csv").getAbsoluteFile();
CsvMapper csvMapper = new CsvMapper();
csvMapper.enable(CsvParser.Feature.WRAP_AS_ARRAY);
MappingIterator<List<String>> rows = csvMapper.readerFor(List.class).readValues(csvFile);
List<Person> persons = rows.readAll().stream()
.filter(row -> !row.isEmpty())
.map(Person::new)
.collect(Collectors.toList());
persons.forEach(System.out::println);
}
}
class Person {
private String name;
private List<String> contacts;
public Person(List<String> row) {
this.name = row.remove(0);
this.contacts = row;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getContacts() {
return contacts;
}
public void setContacts(List<String> contacts) {
this.contacts = contacts;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", contacts=" + contacts +
'}';
}
}
对于您输入的以上代码打印:
Person{name='john', contacts=[john@wick.com, 123 123 123, fb/john.wick]}
Person{name='mike', contacts=[123 0303 11]}
Person{name='dave', contacts=[]}
我认为问题在于列分隔符与数组列分隔符相同。
您可以在 CSV 中使用 ;
而不是 ,
。
应该是:john,john@wick.com;123 123 123;fb/john.wick
这样您就可以继续使用 Jackson 的功能,而不必从字符串列表中手动实例化。
我有 CSV
个文件需要解析。此文件的架构如下:
name, contacts - where contacts are many strings for each person where the number of this contact columns is not regular.
例如:
john, john@wick.com, 123 123 123, fb/john.wick
mike, 123 0303 11
dave,
我正在尝试用 Jacskon CSV
为我的 bean 创建一个 CsvSchema
:
public class Person {
private String name;
private String[] contacts;
}
通过创建自定义架构:
CsvSchema schema = CsvSchema.builder()
.addColumn("name")
.addArrayColumn("contacts", ",")
.build();
但我得到这个:
com.fasterxml.jackson.dataformat.csv.CsvMappingException: Too many entries: expected at most 2
如何用Jackson CSV
解决这样的问题?
Java
代码:
CsvMapper mapper = new CsvMapper();
CsvSchema schema = CsvSchema.builder()
.addColumn("name")
.addArrayColumn("contacts", ",")
.build();
MappingIterator<Person> it = mapper.readerFor(Person.class).with(schema)
.readValues(csvString);
List<Person> all = it.readAll();
您可以使用 CsvParser.Feature.WRAP_AS_ARRAY 功能并将整行读取为 List<String>
。在构造函数中,您可以将 List
转换为 Person
对象。请参阅以下示例:
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvParser;
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
public class CsvApp {
public static void main(String[] args) throws Exception {
File csvFile = new File("./resource/test.csv").getAbsoluteFile();
CsvMapper csvMapper = new CsvMapper();
csvMapper.enable(CsvParser.Feature.WRAP_AS_ARRAY);
MappingIterator<List<String>> rows = csvMapper.readerFor(List.class).readValues(csvFile);
List<Person> persons = rows.readAll().stream()
.filter(row -> !row.isEmpty())
.map(Person::new)
.collect(Collectors.toList());
persons.forEach(System.out::println);
}
}
class Person {
private String name;
private List<String> contacts;
public Person(List<String> row) {
this.name = row.remove(0);
this.contacts = row;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getContacts() {
return contacts;
}
public void setContacts(List<String> contacts) {
this.contacts = contacts;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", contacts=" + contacts +
'}';
}
}
对于您输入的以上代码打印:
Person{name='john', contacts=[john@wick.com, 123 123 123, fb/john.wick]}
Person{name='mike', contacts=[123 0303 11]}
Person{name='dave', contacts=[]}
我认为问题在于列分隔符与数组列分隔符相同。
您可以在 CSV 中使用 ;
而不是 ,
。
应该是:john,john@wick.com;123 123 123;fb/john.wick
这样您就可以继续使用 Jackson 的功能,而不必从字符串列表中手动实例化。