将 Person 和 Address 类视为:
class Person {
String name;
int age;
Address first;
Address second;
}
class Address {
String country;
String city;
}
我想将 csv 文件解析为 Person 对象。示例 csv 文件为:
NAME,AGE,COUNTERY_1,CITY_1,COUNTRY_2,CITY_2
john,50,USA,Arizona,UK,London
bob,27,France,paris,USA,Felorida
我写了一个模型方法:
CsvSchema bootstrapSchema = CsvSchema.emptySchema().withHeader();
CsvMapper mapper = new CsvMapper();
MappingIterator<Person> readValues = mapper
.readerWithTypedSchemaFor(Person.class)
.with(bootstrapSchema)
.readValues(file);
return readValues.readAll();
如何向映射器添加地址类映射?
最佳答案
你不能真正对 jackson 做到这一点,但是 univocity-parsers可以使用其 @Nested
注释:
首先定义您的 Address
类,如下所示:
public static class Address {
@Parsed
String country;
@Parsed
String city;
@Override
public String toString() {
return "Address{country='" + country + '\'' + ", city='" + city + '\'' + '}';
}
}
现在,如果您查看输入,我们需要以某种方式将 header “country_1”和“city_1”与您的 Address
类中的字段关联起来。这是使用自定义 HeaderTransformer 类将索引附加到 header 名称来完成的。让我们这样定义它:
public static class SuffixAppender extends HeaderTransformer {
private String suffix;
public SuffixAppender(String... args) {
suffix = args[0];
}
@Override
public String transformName(Field field, String name) {
return name + "_" + suffix;
}
}
现在您可以使用嵌套的 Address
属性定义您的 Person
类:
public static class Person {
@Parsed
String name;
@Parsed
int age;
@Nested(headerTransformer = SuffixAppender.class, args = "1")
Address first;
@Nested(headerTransformer = SuffixAppender.class, args = "2")
Address second;
@Override
public String toString() {
return "Person{name='" + name + '\'' + ", age=" + age + ", first=" + first + ", second=" + second + '}';
}
}
上面的内容指示解析器获取 Address
中的字段名称,并使用 SuffixAppender
将给定的后缀附加到它。结果将与您输入的标题进行匹配。
最后你就可以解析了。使用解析器的方法有很多种,但最简单的是:
String input = "" +
"NAME,AGE,COUNTRY_1,CITY_1,COUNTRY_2,CITY_2\n" +
"john,50,USA,Arizona,UK,London\n" +
"bob,27,France,paris,USA,Florida";
CsvParserSettings settings = new CsvParserSettings(); //configure the parser
settings.detectFormatAutomatically(); //detects line separators and delimiters
//parse the input with the settings above, into a list of Person objects
List<Person> personList = new CsvRoutines(settings).parseAll(Person.class, new StringReader(input));
让我们看看结果:
Person person1 = personList.get(0);
Person person2 = personList.get(1);
System.out.println(person1);
System.out.println(person2);
输出:
Person{name='john', age=50, first=Address{country='USA', city='Arizona'}, second=Address{country='UK', city='London'}}
Person{name='bob', age=27, first=Address{country='France', city='paris'}, second=Address{country='USA', city='Florida'}}
希望有帮助。
免责声明:我是这个库的作者。它是开源且免费的(Apache 2.0 许可证)
关于java - 复合类的 Jackson CSV 建模器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47966374/