我正在使用HeaderColumnNameMappingStrategy将带有标头的csv文件映射到JavaBean中。字符串值解析正常,但csv中的任何“true”或“false”值都不映射到JavaBean,我从PropertyDescriptor获得以下异常:
java.lang.IllegalArgumentException: argument type mismatch
它出现的代码在CsvToBean第64行:
protected T processLine(MappingStrategy<T> mapper, String[] line) throws
IllegalAccessException, InvocationTargetException, InstantiationException, IntrospectionException {
T bean = mapper.createBean();
for(int col = 0; col < line.length; col++) {
String value = line[col];
PropertyDescriptor prop = mapper.findDescriptor(col);
if (null != prop) {
Object obj = convertValue(value, prop);
// this is where exception is thrown for a "true" value in csv
prop.getWriteMethod().invoke(bean, new Object[] {obj});
}
}
return bean;
}
protected PropertyEditor getPropertyEditor(PropertyDescriptor desc) throws
InstantiationException, IllegalAccessException {
Class<?> cls = desc.getPropertyEditorClass();
if (null != cls) return (PropertyEditor) cls.newInstance();
return getPropertyEditorValue(desc.getPropertyType());
}
我可以确认(通过调试器)此时正确检索到setter方法id。
问题出现在desc.getPropertyEditorClass()中,因为它返回null。我假设原始类型和它的包装器都受支持。他们不是吗?
答案 0 :(得分:5)
我遇到过同样的问题。最干净的方法可能是像上面的pritam一样覆盖getPropertyEditor,并为您的特定对象返回一个自定义PropertyEditor。快速而肮脏的方式是以匿名类形式覆盖convertValue,如下所示:
CsvToBean<MyClass> csvToBean = new CsvToBean<MyClass>(){
@Override
protected Object convertValue(String value, PropertyDescriptor prop) throws InstantiationException,IllegalAccessException {
if (prop.getName().equals("myWhatever")) {
// return an custom object based on the incoming value
return new MyWhatever((String)value);
}
return super.convertValue(value, prop);
}
};
使用OpenCSV 2.3,这对我来说很好。祝你好运!
答案 1 :(得分:1)
我通过扩展CsvToBean并添加我自己的PropertyEditors来解决这个问题。结果是opencsv只支持原始类型而没有包装器。
答案 2 :(得分:0)
Pritam的答案很好,这是处理日期时间格式的示例。
PropertyEditorManager.registerEditor(java.util.Date.class, DateEditor.class);
您应该像这样编写自己的编辑器类:
public class DateEditor extends PropertyEditorSupport{
public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void setAsText(String text){
setValue(sdf.parse(text));}
}