OpenCsv - Register Custom Converter without Annotations



This site utilizes Google Analytics, Google AdSense, as well as participates in affiliate partnerships with various companies including Amazon. Please view the privacy policy for more details.

The other day I was using OpenCsv and needed to register a customer converter to convert a string to a simple object. For whatever reason, using OpenCsv’s annotations wasn’t an option.

After a bit of googlin’ - which led me to an unhelpful post on Stackoverflow and another post on Sourceforge that implied it wasn’t possible - I decided to crack open to source code to see if there indeed was a way.

And there is.

OpenCsv has a class it uses to convert most everything called ConverterPrimitiveTypes. In that class it uses Apache Common’s ConvertUtilsBean class to read and write most everything.

The constructor for ConverterPrimitiveTypes looks like the following:

public ConverterPrimitiveTypes(Class<?> type, String locale, String writeLocale, Locale errorLocale) {
    super(type, locale, writeLocale, errorLocale);
    if(this.locale == null) {
        readConverter = BeanUtilsBean.getInstance().getConvertUtils();
        readConverter.register(true, false, 0);
        readLocaleConverter = null;
    }
    else {
        readLocaleConverter = new LocaleConvertUtilsBean();
        readLocaleConverter.setDefaultLocale(this.locale);
        readConverter = null;
    }
    if(this.writeLocale == null) {
        writeConverter = BeanUtilsBean.getInstance().getConvertUtils();
        writeConverter.register(true, false, 0);
        writeLocaleConverter = null;
    }
    else {
        writeLocaleConverter = new LocaleConvertUtilsBean();
        writeLocaleConverter.setDefaultLocale(this.writeLocale);
        writeConverter = null;
    }
}

To register a new converter, implement the org.apache.commons.beanutils.Converter interface (note that this is different than OpenCsv’s CsvConverter) and register it using BeanUtilsBean like so:

// Assume we have a POJO called MyObject and a converter called MyObjectConverter
var myObjectConverter = new MyObjectConverter();

var beanUtils = BeanUtilsBean.getInstance().getConvertUtils();
beanUtils.register(myObjectConverter, MyObject.class);

Then the next time you try to read your beans using OpenCsv like:

var list = new CsvToBeanBuilder<E>(reader)
    .withType(MyObject.class)
    .build()
    .parse();

It should properly parse using you custom converter.

Leave a Reply

Note that comments won't appear until approved.