我有一个简单的POJO,里面有一个Map。
public class Product {
public Map map;
}
然后我的csv看起来像这样:
"mapEntry1","mapEntry2","mapEntry3"
所以我创建了一个自定义单元处理器来解析它们:
public class MapEntryCellProcessor {
public Object execute(Object val, CsvContext context) {
return next.execute(new AbstractMap.SimpleEntry<>("somekey", val), context);
}
}
然后我在我的产品中添加了一个条目设置器方法:
public void setName(Entry<String, String> entry) {
if (getName() == null) {
name = new HashMap<>();
}
name.put(entry.getKey(), entry.getValue());
}
不幸的是,这意味着我有2个setter方法:一个接受一个map,另一个接受一个对我来说不起作用的条目(我无法控制如何生成POJO)。有没有其他方法可以解析这样的CSV并且只有在我的产品中接受Map的setter?
答案 0 :(得分:1)
可以编写将每列收集到地图中的单元处理器。例如,以下处理器允许您指定要添加到的键和地图。
package org.supercsv.example;
import java.util.Map;
import org.supercsv.cellprocessor.CellProcessorAdaptor;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.util.CsvContext;
public class MapCollector extends CellProcessorAdaptor {
private String key;
private Map<String, String> map;
public MapCollector(String key, Map<String, String> map){
this.key = key;
this.map = map;
}
public MapCollector(String key, Map<String, String> map,
CellProcessor next){
super(next);
this.key = key;
this.map = map;
}
public Object execute(Object value, CsvContext context) {
validateInputNotNull(value, context);
map.put(key, String.valueOf(value));
return next.execute(map, context);
}
}
然后假设您的Product bean有name
类型的字段Map<String,String>
,您可以按如下方式使用处理器。
package org.supercsv.example;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import junit.framework.TestCase;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.prefs.CsvPreference;
public class MapCollectorTest extends TestCase {
private static final String CSV = "John,L,Smith\n" +
"Sally,P,Jones";
public void testMapCollector() throws IOException{
ICsvBeanReader reader = new CsvBeanReader(
new StringReader(CSV),
CsvPreference.STANDARD_PREFERENCE);
// only need to map the field once, so use nulls
String[] nameMapping = new String[]{"name", null, null};
// create processors for each row (otherwise every bean
// will contain the same map!)
Product product;
while ((product = reader.read(Product.class,
nameMapping, createProcessors())) != null){
System.out.println(product.getName());
}
}
private static CellProcessor[] createProcessors() {
Map<String, String> nameMap = new HashMap<String, String>();
final CellProcessor[] processors = new CellProcessor[]{
new MapCollector("name1", nameMap),
new MapCollector("name2", nameMap),
new MapCollector("name3", nameMap)};
return processors;
}
}
输出:
{name3=Smith, name2=L, name1=John}
{name3=Jones, name2=P, name1=Sally}
您会注意到,虽然处理器在所有3列上执行,但它只映射到bean一次(因此nameMapping数组中的空值)。
我每次读取一行时都会创建处理器,否则每个bean都会使用相同的地图......这可能不是你想要的;)