Конвертация с картыPOJO - PullRequest
       37

Конвертация с картыPOJO

1 голос
/ 05 июля 2019

Я создаю класс загрузчика CSV, который читает записи из файлов CSV и возвращает List<T>, где T - целевой класс POJO.

Образец CSV: test.csv

Из извлеченных записей из CSV можно получить значение 0 для поля Date класса POJO. Из образца CSV запишите # 2, где значение createdDate равно 0. Как изменить 0 на действительную дату (например, 1970-01-01 09:00:00), прежде чем произойдет фактическая десериализация?

Я успешно создал процесс чтения файла CSV для преобразования в возвращаемый List<T>.

  1. Разбор: org.apache.commons.csv
  2. Преобразование: com.fasterxml.jackson.databind.ObjectMapper Я имею в виду переопределение некоторых функций моего ObjectMapper для манипулирования значениями, но я не знаю, как это сделать.
private List<T> convertToObjectList(List<Map<String, String>> csvRecordMapList, Class<T> targetClass) {
  List<T> csvRecordObjList = new ArrayList<>();
  SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  ObjectMapper objectMapper = new ObjectMapper();
  objectMapper.setDateFormat(dateFormat);        
  objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
  for(Map<String, String> recordMap : csvRecordMapList)
    csvRecordObjList.add(objectMapper.convertValue(recordMap, targetClass));

  return csvRecordObjList;
}

Если у меня есть 0 для поля Date для целевого класса POJO, я получаю сообщение об ошибке ниже (что уже ожидается):

Can not construct instance of java.util.Date from String value '0': not a valid representation (error: Failed to parse Date value '0': Unparseable date: "0")

Ответы [ 2 ]

1 голос
/ 05 июля 2019

Вместо использования ObjectMapper я использовал org.apache.commons.beanutils.BeanUtils и ConvertUtils.Я узнал, что вы можете добавить индивидуальный конвертер.Ниже приведены мои обновленные исходные коды:

private List<T> convertToObjectList(List<Map<String, String>> csvRecordMapList, Class<T> targetClass)
    throws IllegalAccessException, InvocationTargetException, InstantiationException {
    List<T> csvRecordObjList = new ArrayList<>();
    ConvertUtils.register(getDateConverter(), Date.class);
    for (Map<String, String> recordMap : csvRecordMapList) {
        T targetClassObj = targetClass.newInstance();
        BeanUtils.populate(targetClassObj, recordMap);
        csvRecordObjList.add(targetClassObj);
    }

    return csvRecordObjList;
}

И это мой настроенный конвертер:

private static Converter getDateConverter() {
    return new Converter() {
        @SuppressWarnings({ "unchecked", "rawtypes" })
        @Override
        public Object convert(Class classType, Object value) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = null;
            try {
                date = value.equals("0") ? new Date(0) : sdf.parse((String) value);
            } catch (ParseException e) {
                // Do nothing
            }
            return date;
        }
    };
}
0 голосов
/ 05 июля 2019

Вы можете попробовать что-то вроде этого ниже.(код не скомпилирован).

for(Map<String, String> recordMap : csvRecordMapList) {
    if(recordMap.getKey().equals("createdDate") && recordMap.value().equals("0")) {
        recordMap.put("createdDate", "1970-01-01 09:00:00");
    } 
    csvRecordObjList.add(objectMapper.convertValue(recordMap, targetClass));
}   
...