簡體   English   中英

Spring Batch Json定制ItemWriter

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM