从Map <String,String>转换为POJO

时间:2019-07-05 01:40:06

标签: java csv deserialization objectmapper

我正在创建一个CSV加载程序类,该类从CSV文件读取记录并返回List<T>,其中T是目标POJO类。

样本CSV: test.csv

从CSV提取的记录中,可以为POJO类的0字段获取Date值。在示例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;
}

如果目标POJO类的0字段有Date,我将收到以下错误消息(已经是预期的):

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 个答案:

答案 0 :(得分:0)

您可以在下面尝试类似的方法。 (代码未编译)。

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));
}   

答案 1 :(得分:0)

我使用的是org.apache.commons.beanutils.BeanUtils和ConvertUtils,而不是使用ObjectMapper。我发现您可以添加定制的转换器。以下是我更新的源代码:

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;
        }
    };
}