我想从数据库中写入json格式的文件。我有一个ItemWriter实现的原型,非常简单。
import java.util.ArrayList;
import java.util.List;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.item.ItemWriter;
import org.springframework.core.io.Resource;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class CustomItemWriter<T> implements ItemWriter<T>, StepExecutionListener {
private Gson gson;
private Resource resource;
private boolean shouldDeleteIfExists = true;
private List<T> allItems = new ArrayList<T>();
@Override
public void write(List<? extends T> items) throws Exception {
System.out.println("this is the begin " + items.size());
allItems.addAll(items);
}
public Resource getResource() {
return resource;
}
public void setResource(Resource resource) {
this.resource = resource;
}
public boolean isShouldDeleteIfExists() {
return shouldDeleteIfExists;
}
public void setShouldDeleteIfExists(boolean shouldDeleteIfExists) {
this.shouldDeleteIfExists = shouldDeleteIfExists;
}
@Override
public ExitStatus afterStep(StepExecution arg0) {
//write ALL to the output file
System.out.println(gson.toJson(allItems));
return null;
}
@Override
public void beforeStep(StepExecution arg0) {
gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").disableHtmlEscaping().create();
}
}这里解决的问题是,write方法将每个commitInterval发送给输出文件一个JSON数组,我只是希望文件中有一个惟一的JSON数组。
步骤运行后实现StepExecutionListener;我可以将整个数组发送到输出文件,并将其转换为JSON,并将其写入输出文件(很好!)。
我的问题是,是这样做的正确方法吗?,我认为写到每个commitInterval文件的好处,但我不确定我的解决方案。这是可行的,但我不想解决这个问题,去证明另一个问题。
发布于 2016-05-25 16:59:45
实际上,您希望用每个块来刷新对文件的写入,否则就会失去重新启动的能力。
假设您对每行一个JSON对象都满意,我可能只会使用一个FlatFileItemWriter和一个自定义LineAggregator来将每个对象转换成一个JSON字符串。类似于这样的东西:
public class JsonLineAggregator<T> implements LineAggregator<T>, StepExecutionListener {
private Gson gson = new Gson();
private boolean isFirstObject = true;
@Override
public String aggregate(final T item) {
if (isFirstObject) {
isFirstObject = false;
return "[" + gson.toJson(item);
}
return "," + gson.toJson(item);
}
public void setGson(final Gson gson) {
this.gson = gson;
}
@Override
public void beforeStep(final StepExecution stepExecution) {
if (stepExecution.getExecutionContext().containsKey("isFirstObject")) {
isFirstObject = Boolean.parseBoolean(stepExecution.getExecutionContext().getString("isFirstObject"));
}
}
@Override
public ExitStatus afterStep(final StepExecution stepExecution) {
stepExecution.getExecutionContext().putString("isFirstObject", Boolean.toString(isFirstObject));
return null;
}
}编辑:更新了上面的LineAggregator实现,以演示如何使其输出类似于JSON列表的内容。
请注意,您还希望将一个FlatFileFooterCallback注册到添加最终"]“的FlatFileItemWriter中。
public class JsonFlatFileFooterCallback implements FlatFileFooterCallback {
@Override
public void writeFooter(final Writer writer) throws IOException {
writer.write("]");
}
}发布于 2017-09-26 12:02:49
谢谢你的解决方案。
在Xml中,可以这样添加。
<property name="resource" value="file:opt/output.json" /> <!-- #{jobParameters['input.file.name']} -->
<property name="shouldDeleteIfExists" value="true" />
<property name="lineAggregator">
<bean
class="com.package.JsonLineAggregator">
</bean>
</property>
</bean> https://stackoverflow.com/questions/37443046
复制相似问题