2

CSVBeanReader公开读取给定类型 bean 的方法

有没有办法传递一个实际的对象实例而不是对象类型(即自定义 bean 实例化)?

4

1 回答 1

1

Update:

I've just released Super CSV 2.2.0, which enables CsvBeanReader and CsvDozerBeanReader to both populate an existing bean. Yay!


I'm a Super CSV developer. There's no way to do this using the readers supplied with Super CSV (CsvBeanReader and CsvDozerBeanReader) and it hasn't come up as a feature request before. You could submit a feature request and we'll consider adding it in the next release (which I'm hoping to get out this month).

The quickest solution for you is to write your own CsvBeanReader that allows this - just copy the source of CsvBeanReader into yours and modify as required.

I'd start by refactoring the populateBean() method into 2 methods (overloaded so one calls the other).

  /**
   * Instantiates the bean (or creates a proxy if it's an interface), and maps the processed columns to the fields of
   * the bean.
   * 
   * @param clazz
   *            the bean class to instantiate (a proxy will be created if an interface is supplied), using the default
   *            (no argument) constructor
   * @param nameMapping
   *            the name mappings
   * @return the populated bean
   * @throws SuperCsvReflectionException
   *             if there was a reflection exception while populating the bean
   */
  private <T> T populateBean(final Class<T> clazz, final String[] nameMapping) {

    // instantiate the bean or proxy
    final T resultBean = instantiateBean(clazz);

    return populateBean(resultBean, nameMapping);
  }

  /**
   * Populates the bean by mapping the processed columns to the fields of the bean.
   * 
   * @param resultBean
   *            the bean to populate
   * @param nameMapping
   *            the name mappings
   * @return the populated bean
   * @throws SuperCsvReflectionException
   *             if there was a reflection exception while populating the bean
   */
  private <T> T populateBean(final T resultBean, final String[] nameMapping) {

    // map each column to its associated field on the bean
    for( int i = 0; i < nameMapping.length; i++ ) {

      final Object fieldValue = processedColumns.get(i);

      // don't call a set-method in the bean if there is no name mapping for the column or no result to store
      if( nameMapping[i] == null || fieldValue == null ) {
        continue;
      }

      // invoke the setter on the bean
      Method setMethod = cache.getSetMethod(resultBean, nameMapping[i], fieldValue.getClass());
      invokeSetter(resultBean, setMethod, fieldValue);

    }

    return resultBean;
  }

You can then write your own read() methods (based on the ones from CsvBeanReader), that accept bean instances (instead of their class), and call the populateBean() that accepts an instance.

I'll leave this as an exercise for you, but if you have any questions just ask :)

于 2013-02-06T09:52:38.033 回答