Can anyone help please?
I am stuck on reading a csv file and serializing it onto a POJO.
I am using CsvMapper from jackson library. The reading and serialization part are done and works fine-ish. The issue is when the user moves the headers/columns around causing the serialization to make some alphabetical assumption that the values on the CSV file are also alphabetically.
Eg (File below has headers on the first row and the second row has person details values)
personNameHeader,personAgeHeader
Wiliam,32
Now my POJO is as follow
@JsonIgnoreProperties(ignoreUnknown = true)
// @JsonPropertyOrder(value = {"personNameHeader", "personAgeHeader" })
public class PersonDetailsCSVTemplate {
@JsonProperty("personNameHeader")
private String name;
@JsonProperty("personAgeHeader")
private String age;
//Public constructor and getters and setters...
This is the code to read the values from the CSV and map onto the class
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
...
CsvMapper csvMapper = new CsvMapper();
CsvSchema schema = csvMapper.typedSchemaFor(PersonDetailsCSVTemplate.class).withHeader();
MappingIterator<PersonDetailsCSVTemplate > dataIterator = csvMapper.readerFor(PersonDetailsCSVTemplate.class).with(schema)
.readValues(data);
while (dataIterator.hasNextValue()) {
PersonDetailsCSVTemplate dataCSV = dataIterator.nextValue();
}
After the serialization it can be seen that CsvMapper mapped the following:
PersonDetailsCSVTemplate.name = "32"
andPersonDetailsCSVTemplate.age = "Wiliam"
By annotating the class with @JsonPropertyOrder(value = {"personNameHeader", "personAgeHeader" })
forces the CSV to be always name column followed by age column which isnt ideal.
Can anyone suggest anything that they think will work? Regards
Since Jackson 2.7, you can use withColumnReordering(true)
instead of sortedBy()
CsvSchema schema = csvMapper
.typedSchemaFor(PersonDetailsCSVTemplate.class)
.withHeader()
.withColumnReordering(true);
You could use sortedBy and give it the order in which the properties apeare in your csv data:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonPropertyOrder(value = { "personNameHeader", "personAgeHeader" })
static class PersonDetailsCSVTemplate
{
@JsonProperty("personNameHeader")
private String name;
@JsonProperty("personAgeHeader")
private String age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getAge()
{
return age;
}
public void setAge(String age)
{
this.age = age;
}
@Override
public String toString()
{
return "PersonDetailsCSVTemplate [name=" + name + ", age=" + age + "]";
}
}
You can keep or leave @JsonPropertyOrder
it won't affect the output.
@Test
public void sort() throws IOException
{
CsvMapper csvMapper = new CsvMapper();
CsvSchema schema = csvMapper
.typedSchemaFor(PersonDetailsCSVTemplate.class)
.withHeader()
.sortedBy("personNameHeader", "personAgeHeader")
.withColumnSeparator(',')
.withComments();
MappingIterator<PersonDetailsCSVTemplate> dataIterator =
csvMapper
.readerFor(PersonDetailsCSVTemplate.class)
.with(schema)
.readValues("personNameHeader,personAgeHeader\r\n"
+
"Wiliam,32\r\n");
while (dataIterator.hasNextValue())
{
PersonDetailsCSVTemplate dataCSV = dataIterator.nextValue();
System.out.println(dataCSV);
}
}
Output:
PersonDetailsCSVTemplate [name=Wiliam, age=32]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With