2012-09-26 10 views
5

Ich versuche, eine CSV-Datei mit Jackson CsvParser in ein Objekt zu analysieren, das auch eine Liste einer anderen Klasse enthält.Java Jackson: Analysieren einer CSV-Datei in ein Objekt mit einer Liste von Objekten

Also die ersten 2 Spalten enthalten Daten, die an die Elternklasse gebunden werden müssen, und die Daten müssten anschließend an eine andere Klasse gebunden werden.

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 
} 

Das Protokoll würde so aussehen analysiert werden:

John Doe, 30, Honda, D32GHF 

Oder in einem anderen Protokoll des Benutzers kann es aussehen mit 2 Autos:

die ersten 2 zu analysieren
Jane Doe, 29, Mini, F64RTZ, BMW, T56DFG 

Daten in der Klasse "Person" sind kein Problem.

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

Aber ich kann die CarDetails nicht analysieren. Es scheint, als ob ich in der Lage sein muss, nach dem Wert zu suchen, ein neues CarDetails-Objekt zu erstellen und es dem Person-Objekt hinzuzufügen, aber ich kann nicht sehen, wie ich diese Informationen extrahiere.


Meine Lösung ist folgende:

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

Antwort

4

Wenn Sie CsvMapper.readerWithSchemaFor am Javadoc aussehen, heißt es:

keine CSV-Typen abgebildet werden können, um Arrays oder Sammlungen

+1

Ja, es scheint, es gibt keinen sauberen Weg, dies zu tun. In der Zwischenzeit habe ich mich jedoch entschieden, alles einfach in eine Map zu schreiben und das Schema zu verwenden, um Schlüssel zu identifizieren und die Klassen manuell aufzufüllen. Hatte gehofft es gäbe einen besseren Weg. Danke für deinen Beitrag. (Ich poste meine Lösung als Update und akzeptiere deine Antwort). – DanF7

+0

Beachten Sie, dass Sie diese Art der Konvertierung durchführen können, wenn Sie einen benutzerdefinierten Serializer und Deserializer hinzufügen. Sie können dafür sogar den Standard-JSON 'ObjectMapper' verwenden. – StaxMan

+1

Mit späteren Versionen (2.5 und höher) unterstützt Jackson tatsächlich einfache List/Array-Typen, deren Wert Skalare wie Strings, Enums oder Zahlen sind. Trennzeichen ist standardmäßig Semikolon (";"), kann aber für ein anderes Zeichen konfiguriert werden. Dies würde leider nicht für Ihren Fall funktionieren, da Sie dasselbe Trennzeichen wie Spalten verwenden; und Werttypen sind ebenfalls komplexer. Aber ich fand es erwähnenswert, wenn andere nach einer einfacheren Verwendung von Listen/Arrays suchen. – StaxMan

Verwandte Themen