2012-09-26 86 views
5

Estoy tratando de analizar un archivo csv utilizando Jackson CsvParser en un objeto que también contiene una lista de otra clase.Java Jackson: análisis de un archivo csv en un objeto que contiene una lista de objetos

Por lo tanto, las primeras 2 columnas contienen datos que deben vincularse a la clase principal y los datos posteriores deberán vincularse a otra clase.

public class Person { 
    private String name; 
    private String age; 
    private List<CarDetails> carDetails; 

    //Getters+setters 
} 

public class CarDetails { 
    private String carMake; 
    private String carRegistration; 

    //Getters+setters 
} 

El registro para ser analizada se vería así:

John Doe, 30, Honda, D32GHF 

O en otro registro de usuarios de todo con 2 coches que puede parecer:

Jane Doe, 29, Mini, F64RTZ, BMW, T56DFG 

para analizar la inicial 2 los elementos de datos a la clase "Persona" no son un problema.

CsvMapper mapper = new CsvMapper(); 
CsvSchema schema = CsvSchema.builder() 
    .addColumn("name") 
    .addColumn("age") 

for(numberOfCars=2; numberOfCars!=0 ; numberOfCars--) 
    schema = schema.rebuild() 
     .addColumn("carMake") 
     .addColumn("carRegistration") 

MappingIterator<Map.Entry> it = mapper 
    .reader(Person.class) 
    .with(schema) 
    .readValues(personLog); 
    List<Person> people = new ArrayList<Person>(); 
    while (it.hasNextValue()) { 
     Person person = (Person) it.nextValue(); 
     people.add(person); 
    } 

Pero no sé cómo analizar los CarDetails. Parece que tengo que poder buscar el valor, crear un nuevo objeto CarDetails y agregarlo al objeto Person, pero no puedo ver cómo extraer esa información.


Mi solución es la siguiente:

List<Person> people = new ArrayList<Person>(); 

MappingIterator<Map<?,?>> it = mapper.reader(schema).withType(Map.class).readValues(personLog); 
while(it.hasNextValue()) { 
    Person person = new Person(); 
    CarDetails = new CarDetails(); 
    Map<?,?> result = it.nextValue(); 
    person.setName(result.get("name").toString()); 
    carDetails.setCarMake(result.get("carMake").toString()); 
    person.addCarDetails(carDetails); 
    people.add(person); 
}  

Respuesta

4

Si nos fijamos en el Javadoc para CsvMapper.readerWithSchemaFor, se indica:

ningún tipo CSV se pueden asignar a las matrices o colecciones

+1

Sí, parece que no hay una manera clara de hacerlo. Sin embargo, mientras tanto, decidí simplemente volcar todo en un mapa y usar el esquema para identificar las claves y completar las clases manualmente. Esperaba que hubiera una mejor manera. Gracias por tu contribución. (Publicaré mi solución como una actualización y acepto su respuesta). – DanF7

+0

Tenga en cuenta que si agrega un serializador y un deserializador personalizados, puede hacer este tipo de conversión. Incluso podría usar JSON 'ObjectMapper' estándar para esto. – StaxMan

+1

Con versiones posteriores (2.5 y superiores), Jackson EN REALIDAD admite tipos List/array simples, donde el valor son escalares como cadenas, enumeraciones o números. Separadores es, por defecto, punto y coma (";"), pero se puede configurar a otro personaje. Esto no funcionaría desafortunadamente para su caso ya que está usando el mismo separador que las columnas; y los tipos de valores son más complejos también. Pero pensé que valía la pena mencionar si otros buscan un uso más simple de List/array. – StaxMan

Cuestiones relacionadas