Spring BeanWrapperFieldExtractor FlatFileItemWriter 忽略缺失的空字段

Spring BeanWrapperFieldExtractor FlatFileItemWriter ignore missing null fields

我想写入一个 csv 文件,忽略为空的对象字段。

目前它写道:

测试,PBAFFF,

对象中的第三个和第四个值可以为空。

我如何配置 FlatFileItemWriterBeanWrapperFieldExtractor,它只会写入非 null 字段的文件?

我的编写器配置如下:

csvWriter.setLineAggregator(new DelimitedLineAggregator<Transaction>() {
    {
        setDelimiter(",");

        setFieldExtractor(new BeanWrapperFieldExtractor<Transaction>() {
            {
                setNames(new String[] { "id", "source", "startDate", "endDate"});
            }
        });
    }
});

有两种方法可以做到这一点:

  • 实施您的自定义 LineAggregator
public class NullSafeDelimitedLineAggregator<T> extends ExtractorLineAggregator<T> {

        private String delimiter;

        public NullSafeDelimitedLineAggregator(String delimiter, FieldExtractor<T> fieldExtractor) {
            this.delimiter = delimiter;
            setFieldExtractor(fieldExtractor);
        }

        @Override
        public String doAggregate(Object[] fields) {
            return arrayToDelimitedString(fields, delimiter);
        }

        private String arrayToDelimitedString(@Nullable Object[] arr, String delim) {
            if (ObjectUtils.isEmpty(arr)) {
                return "";
            }
            if (arr.length == 1) {
                return ObjectUtils.nullSafeToString(arr[0]);
            }

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < arr.length; i++) {
                if(arr[i] == null || "".equals(arr[i])) {
                    continue;
                }
                if (i > 0) {
                    sb.append(delim);
                }
                sb.append(arr[i]);
            }
            return sb.toString();
        }
    }

并按以下方式更改配置:

writer.setLineAggregator(new NullSafeDelimitedLineAggregator<>(
                ",",
                new BeanWrapperFieldExtractor<Transaction>() {
                    {
                        setNames(new String[] { "id", "source", "startDate", "endDate"});
                    }
                }));

  • 实施您的自定义 FieldExtractor
public class NullSafeBeanWrapperFieldExtractor<T> implements FieldExtractor<T>, InitializingBean {

        private String[] names;

        public void setNames(String[] names) {
            Assert.notNull(names, "Names must be non-null");
            this.names = Arrays.asList(names).toArray(new String[names.length]);
        }

        @Override
        public Object[] extract(T item) {
            List<Object> values = new ArrayList<Object>();

            BeanWrapper bw = new BeanWrapperImpl(item);
            for (String propertyName : this.names) {
                Object value = bw.getPropertyValue(propertyName);
                if(value == null || "".equals(value)) {
                    continue;
                }
                values.add(value);
            }
            return values.toArray();
        }

        @Override
        public void afterPropertiesSet() {
            Assert.notNull(names, "The 'names' property must be set.");
        }

    }

并按以下方式更改配置:

 writer.setLineAggregator(new DelimitedLineAggregator<Transaction>() {
            {
                setDelimiter(",");
                setFieldExtractor(new NullSafeBeanWrapperFieldExtractor<Transaction>() {
                    {
                        setNames(new String[] { "id", "source", "startDate", "endDate"});
                    }
                });
            }
        });

重要提示:您应该根据一个问题选择两个选项之一:知道数组中有多少个值对您来说很重要吗?如果是 - LineAggregator,否 - FieldExtractor.