I'm creating a CSV loader class which reads records from CSV files and returns a List<T>
where T is the target POJO class.
Sample CSV:
From the extracted records from CSV, it is possible to get 0
value for a Date
field of a POJO class. From the sample CSV, record #2 where the value of createdDate
is 0
. How do I change 0
to a valid date (e.g 1970-01-01 09:00:00
) first before the actual deserialization happens?
I have successfully created the process of reading a CSV file to conversion to returning List<T>
.
org.apache.commons.csv
com.fasterxml.jackson.databind.ObjectMapper
I am thinking of overriding some functions of my ObjectMapper
to manipulate the values, but I have no idea how to do it.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;
}
If I have 0
for a Date
field for the target POJO class, I get the error message below (which is already expected):
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")
Instead of using ObjectMapper, I used org.apache.commons.beanutils.BeanUtils and ConvertUtils. I found out that you can add a customized converter. Below are my updated source codes:
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;
}
And this is my customized converter:
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;
}
};
}