Jackson CSV Mapper无法正确映射CSV内容:表头与值不匹配?
问题:CSV数据映射到Java对象时字段匹配错误
我有一个CSV文件pets.csv:
NUMBER,NAME,TYPE 1,Jack,Dog 2,Russel,Cat 3,Great,Mouse
我为每个宠物定义了自定义类Pet:
@JsonPropertyOrder({ "NUMBER", "NAME", "TYPE" }) public class Pet { public String number; public String name; public String type; }
随后在主类中,我希望将pets.csv的数据读取到List<Pet>中:
public static void main(String[] args) throws IOException { List<Pet> pets = readFile(Path.of("pets.csv")); pets.forEach(pet -> System.out.println(pet.name)); } public static List<Pet> readFile(Path csvFile) throws IOException { try(MappingIterator<Pet> petIter = new CsvMapper() .readerWithTypedSchemaFor(Pet.class).readValues(csvFile.toFile())) { return petIter.readAll(); } }
但预期输出应为:
Jack Russel Great
实际却得到:
1 2 3
请问我哪里出错了?
问题原因与解决方法
原因
Jackson CSV默认按Java类的字段声明顺序匹配CSV列,你的Pet类字段顺序是number→name→type,对应CSV的第1、2、3列,导致name字段被错误赋值为CSV第一列(NUMBER列)的内容。而@JsonPropertyOrder注解仅作用于**序列化(写CSV)**时的字段输出顺序,对反序列化(读CSV)的列匹配逻辑无影响。
解决方法
有两种可行的修改方案:
方案1:给字段添加@JsonProperty指定对应列名
直接在每个字段上标注对应的CSV列名,明确映射关系:
public class Pet { @JsonProperty("NUMBER") public String number; @JsonProperty("NAME") public String name; @JsonProperty("TYPE") public String type; }
方案2:开启Jackson CSV的列名匹配特性
修改读取CSV的代码,启用USE_COLUMN_NAMES_AS_PROPERTIES特性,让Jackson根据CSV列名和Java字段名(大小写不敏感)自动匹配:
public static List<Pet> readFile(Path csvFile) throws IOException { CsvMapper mapper = new CsvMapper(); // 启用按列名匹配字段的特性 mapper.enable(CsvParser.Feature.USE_COLUMN_NAMES_AS_PROPERTIES); try(MappingIterator<Pet> petIter = mapper .readerWithTypedSchemaFor(Pet.class).readValues(csvFile.toFile())) { return petIter.readAll(); } }
两种方案都能让name字段正确匹配CSV的NAME列,执行后即可得到预期输出。
内容的提问来源于stack exchange,提问作者armaka
相关产品推荐
相关产品推荐

