[英]Spring Batch Json custom ItemWriter
我想從數據庫中寫入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
寫入文件都commitInterval
,但是我不確定我的解決方案。 它有效,但是我不想解決這個問題並提出另一個問題。
您實際上希望將每個塊刷新到文件的寫入中,否則將失去可重新啟動性。
假設您可以每行使用一個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("]");
}
}
感謝您的解決方案。
在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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.