简体   繁体   English

Spring BeanWrapperFieldExtractor FlatFileItemWriter 忽略缺少的 null 字段

[英]Spring BeanWrapperFieldExtractor FlatFileItemWriter ignore missing null fields

I want to write to a csv file ignoring object field which are null.我想写入 csv 文件,忽略 null 字段的 object 字段。

Currently it writes:目前它写道:

Test,PBAFFF,,测试,PBAFFF,,

The 3rd and 4th values can be null in the object.第 3 和第 4 个值可以是 object 中的 null。

How can I configure FlatFileItemWriter with BeanWrapperFieldExtractor which would only write to file the non null fields?如何使用BeanWrapperFieldExtractor配置FlatFileItemWriter ,它只会写入非null字段的文件?

I have my writer configured like this:我的作家配置如下:

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

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

There are two ways to do this:有两种方法可以做到这一点:

  • Implement your custom LineAggregator实现您的自定义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();
        }
    }

And change config in following way:并通过以下方式更改配置:

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

  • Implement your custom FieldExtractor实现您的自定义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.");
        }

    }

And change config in following way:并通过以下方式更改配置:

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

Important: You should chose one of two options based on one question: is it important for you to know how many values you have in the array or not?重要提示:您应该根据一个问题选择两个选项之一:知道数组中有多少个值对您来说重要吗? if yes - LineAggregator , no - FieldExtractor .如果是 - LineAggregator ,否 - FieldExtractor

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM