Схема Джексона-CSV для массива - PullRequest
2 голосов
/ 07 июля 2019

У меня есть CSV файл, который мне нужно проанализировать. Схема для этого файла следующая:

имя, контакты - где в контактах много строк для каждого человека, где количество столбцов этого контакта не является регулярным.

Например:

john, john@wick.com, 123 123 123, fb/john.wick
mike, 123 0303 11
dave,

Я пытаюсь создать CsvSchema с Jacskon CSV для моего компонента:

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();

1 Ответ

0 голосов
/ 09 июля 2019

Вы можете использовать функцию 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=[]}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...