我想从数据库中编写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
写入文件,但我不确定我的解决方案。它有效,但我不想解决这个问题并挑起另一个问题。
答案 0 :(得分:1)
您希望实际使用每个块刷新对文件的写入,否则您将失去可重启性。
假设你对每行一个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
注册添加了最终“{1}}的{{1}}。
FlatFileItemWriter
答案 1 :(得分:0)
感谢您的解决方案。
在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>