class MyPOJO implements Serializable
{
private static final long serialVersionUID = 1L;
@Parsed(field = "UniqueCode")
private String code;
@Parsed(field = "Name")
private String name;
@Parsed(field = "dogId")
private String someOtherId;
//------Getters and Setters-------
public String getCode()
{
return code;
}
public void setCode(String code)
{
this.code = code;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getSomeOtherId()
{
return someOtherId;
}
public void setSomeOtherId(String someOtherId)
{
this.someOtherId = someOtherId;
}
}
现在我需要映射一个字段,例如someOtherId具有多个标题名称(例如:" dogId"," catId"," cowId"等)来自不同的csv文件。因此,假设文件 1.csv ,名为dogId
的标题列应映射到POJO字段someOtherId
,而在文件 2.csv 标题{{} 1}}应该映射到同一个字段,即catId
。可能吗?怎么样?
答案 0 :(得分:2)
如果someOtherId
值的列始终位于同一位置,无论您使用的是哪个文件,都可以轻松解析此问题。
class MyPOJO implements Serializable
{
private static final long serialVersionUID = 1L;
@Parsed(field = "UniqueCode")
private String code;
@Parsed(field = "Name")
private String name;
@Parsed(index = 2) //anything goes here, "catId", "cowId", etc
private String someOtherId;
...
}
如果每个输入文件中的列位置不同,您可以实现自己的行处理器。我创建了以下可能适合您的实现。它实质上将可能的标头映射到索引。这些索引应该与您的类中注释的索引匹配。
我打破细节,帮助你理解我的所作所为。
@Parsed(index = 0)
private String code;
@Parsed(index = 1)
private String name;
@Parsed(index = 2) //cowId, dogId or catId or anything else
private String someOtherId;
public class MyBeanProcessor<T> extends AbstractRowProcessor{
//here's the wrapped bean processor.
private final BeanListProcessor<T> processor;
//we need a LinkedHashMap here to keep the the correct ordering.
private final LinkedHashMap<String, Integer> headersToCapture;
public MyBeanProcessor(Class<T> beanType, LinkedHashMap<String, Integer> headersToCapture){
processor = new BeanListProcessor<T>(beanType);
this.headersToCapture = headersToCapture;
}
// work with parsed headers to find out what is in the input
@Override
public void rowProcessed(String[] inputRow, ParsingContext context) {
//... more details later
}
@Override
public void processEnded(ParsingContext context) {
processor.processEnded(context);
}
public List<T> getBeans(){
return processor.getBeans();
}
}
//keys are possible headers, and values are the indexes where each header will be mapped to:
Map<String, Integer> headerPositions = new LinkedHashMap<String, Integer>();
headerPositions.put("UniqueCode", 0);
headerPositions.put("Name", 1);
headerPositions.put("dogId", 2);
headerPositions.put("catId", 2);
headerPositions.put("cowId", 2);
CsvParserSettings settings = new CsvParserSettings();
//we want headers
settings.setHeaderExtractionEnabled(true);
//let's use the custom row processor:
MyBeanProcessor<MyPOJO> processor = new MyBeanProcessor<MyPOJO>(MyPOJO.class, headerPositions);
settings.setRowProcessor(processor);
CsvParser parser = new CsvParser(settings);
parser.parse(<YOUR_INPUT_HERE>);
List<MyPOJO> myPojos = processor.getBeans();
rowProcessed
方法的实施: private int[] headerIndexes = null;
private String[] row = null;
@Override
public void rowProcessed(String[] inputRow, ParsingContext context) {
if(headerIndexes == null){ //initializes the indexes to capture
processor.processStarted(context);
String[] parsedHeaders = context.headers();
LinkedHashSet<Integer> indexes = new LinkedHashSet<Integer>();
for(String headerToCapture : headersToCapture.keySet()){
int headerIndex = ArgumentUtils.indexOf(parsedHeaders, headerToCapture);
if(headerIndex != -1){
indexes.add(headerIndex);
}
}
headerIndexes = ArgumentUtils.toIntArray(indexes);
row = new String[indexes.size()]; //creates a reusable row with the number of columns captured
}
//once the input format is known, we can collect the values from the expected positions:
for(int i = 0; i < headerIndexes.length; i++){
int indexToCapture = headerIndexes[i];
if(indexToCapture < inputRow.length){
row[i] = inputRow[indexToCapture];
} else {
row[i] = null;
}
}
//and submit a row with the values in the correct places to the actual bean processor
processor.rowProcessed(row, context);
}
我在本地对此进行了测试,无论头部位于何处,都会按预期解析以下输入:
UniqueCode,T,name,dogId
1,99,2,3
制作
MyPOJO{code='1', name='2', someOtherId='3'}
cowId,Z,UniqueCode,T,name
4,99,5,99,6
制作
MyPOJO{code='5', name='6', someOtherId='4'}
希望这有帮助。