[英]Parse CSV with extra columns which are not defined in POJO using Jackson
I am trying to parse a CSV and serialize it using the Jackson library.我正在尝试解析 CSV 并使用 Jackson 库对其进行序列化。 I have tried several methods but can't get to ignore the extra columns in the CSV which are not defined in the POJO.我尝试了几种方法,但无法忽略 CSV 中未在 POJO 中定义的额外列。 Requirements:要求:
I have already tried @JsonIgnoreProperties(true)
and also tried to use DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
but nothing seems to work properly.我已经尝试过@JsonIgnoreProperties(true)
并且也尝试过使用DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
但似乎没有什么能正常工作。
POJO: POJO:
public class student{
@JsonProperty("STUDENT_NAME")
private String name;
@JsonProperty("DOB")
private String dateOfBirth;
@JsonProperty("ID")
private String id;
}
CSV: CSV:
STUDENT_NAME,ID,STANDARD,DOB
John,1,4,01/02/2000
Doe,2,5,02/01/1999
I believe the issue is that you need to specify a specific Schema.我认为问题在于您需要指定特定的架构。
For the Student class defined thusly:对于如此定义的学生 class:
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Student
{
@JsonProperty("STUDENT_NAME")
private String name;
@JsonProperty("DOB")
private String dateOfBirth;
@JsonProperty("ID")
private String id;
...
}
This approach appears to work (tested using a String input, but obviously can change to read a file):这种方法似乎有效(使用 String 输入进行测试,但显然可以更改为读取文件):
public static List<Student> parse(String inp) throws IOException
{
CsvSchema schema = CsvSchema.builder()
.addColumn("STUDENT_NAME")
.addColumn("ID")
.addColumn("DOB")
.setReorderColumns(true)
.setUseHeader(true)
.build();
CsvMapper mapper = new CsvMapper();
MappingIterator<Student> iter = mapper
.readerFor(Student.class)
.with(schema)
.readValues(inp);
List<Student> students = new ArrayList<>();
while (iter.hasNext()) {
students.add(iter.next());
}
return students;
}
Tested via:通过测试:
final String example = "STUDENT_NAME,ID,STANDARD,DOB\n"
+ "John,1,4,01/02/2000\n"
+ "Doe,2,5,02/01/1999";
@org.junit.Test
public void testViaInp() throws IOException
{
List<Student> students = ParseCsvWithJackson.parse(example);
Assert.assertNotNull("null students", students);
Assert.assertEquals("Wrong # of students", 2, students.size());
Student first = students.get(0);
Assert.assertEquals("Wrong name", "John", first.getName());
Assert.assertEquals("Wrong id", "1", first.getId());
System.out.println(first);
}
Update: I added a test to use a csv file, and it passed the same tests with the one caveat that I needed to set skip empty lines as a blank line at the end of the file was creating an entry with null values.更新:我添加了一个使用 csv 文件的测试,它通过了相同的测试,但有一个警告,我需要设置跳过空行,因为文件末尾的空行正在创建一个具有 null 值的条目。
private static CsvSchema getSchema()
{
return CsvSchema.builder().addColumn("STUDENT_NAME").addColumn("ID")
.addColumn("DOB").setReorderColumns(true).setUseHeader(true)
.build();
}
private static CsvMapper getMapper()
{
CsvMapper mapper = new CsvMapper();
mapper.enable(CsvParser.Feature.SKIP_EMPTY_LINES);
return mapper;
}
public static List<Student> parse(Path csvfile) throws IOException
{
CsvSchema schema = getSchema();
CsvMapper mapper = getMapper();
MappingIterator<Student> iter = mapper.readerFor(Student.class)
.with(schema).readValues(csvfile.toFile());
List<Student> students = new ArrayList<>();
while (iter.hasNext()) {
students.add(iter.next());
}
return students;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.