Spring BeanWrapperFieldExtractor FlatFileItemWriter 忽略缺失的空字段
Spring BeanWrapperFieldExtractor FlatFileItemWriter ignore missing null fields
我想写入一个 csv 文件,忽略为空的对象字段。
目前它写道:
测试,PBAFFF,
对象中的第三个和第四个值可以为空。
我如何配置 FlatFileItemWriter
和 BeanWrapperFieldExtractor
,它只会写入非 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
.
我想写入一个 csv 文件,忽略为空的对象字段。
目前它写道:
测试,PBAFFF,
对象中的第三个和第四个值可以为空。
我如何配置 FlatFileItemWriter
和 BeanWrapperFieldExtractor
,它只会写入非 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
.