как анализировать нестроковые значения в Opencsv HeaderColumnNameMappingStrategy

Я использую HeaderColumnNameMappingStrategy для сопоставления CSV-файла с заголовком с JavaBean. Строковые значения анализируются нормально, но любое значение "true" или "false" в csv не сопоставляется с 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());
}

Я могу подтвердить (через отладчик), что идентификатор метода установки правильно получен в этот момент.

Проблема возникает в desc.getPropertyEditorClass(), так как он возвращает значение null. Я предположил, что поддерживаются примитивные типы и их оболочки. Разве это не так?


person pri    schedule 29.11.2011    source источник


Ответы (3)


Я столкнулся с этой же проблемой. Самый чистый способ, вероятно, переопределить getPropertyEditor, как это сделал pritam выше, и вернуть пользовательский 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. Удачи!

person Nathan Beach    schedule 13.09.2012

Я решил эту проблему, расширив CsvToBean и добавив свои собственные редакторы свойств. Оказывается, opencsv поддерживает только примитивные типы и не поддерживает обертки.

person pri    schedule 01.12.2011
comment
случайно, если вы помните, как вы на самом деле создали свои собственные редакторы свойств? - person Jatin Sehgal; 25.05.2015
comment
Регистрация собственного редактора может не сработать, поскольку BooleanEditor уже зарегистрирован. Чтобы зарегистрировать редактор, вы должны вызвать: PropertyEditorManager.registerEditor(Integer.class, IntegerEmptyEditor.class); - person Remy Mellet; 15.11.2015

Ответ Притама великолепен, и это пример работы с форматом даты и времени.
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));} }

person xialedoucaicai    schedule 28.11.2018