Java >> Java Tutorial >  >> Tag >> Spring

Spring Batch Tutorial:Schreiben von Informationen in eine CSV-Datei

In den vorherigen Teilen dieses Tutorials haben Sie gelernt, die Eingabedaten Ihres Batch-Jobs aus verschiedenen Datenquellen zu lesen. Ihr Batch-Job ist jedoch nicht sehr nützlich, da Sie nicht wissen, wie Sie die Ausgabedaten Ihres Batch-Jobs speichern können.

Dieses Mal lernen Sie, die Ausgabedaten Ihres Spring Batch-Jobs in eine CSV-Datei zu schreiben. Nachdem Sie diesen Blogbeitrag gelesen haben, werden Sie:

  • Wissen, wie Sie einer CSV-Datei eine Kopfzeile hinzufügen können.
  • Verstehen Sie, wie Sie Ihr Domänenobjekt in eine Zeile umwandeln können, die in eine CSV-Datei geschrieben wird.
  • Kann die Ausgabedaten Ihres Batch-Jobs in eine CSV-Datei schreiben.

Beginnen wir mit einem kurzen Blick auf Ihren Batch-Job.

Einführung in Ihren Batch-Job

Der Beispiel-Batch-Job dieses Blogbeitrags verarbeitet die Studenteninformationen eines Online-Kurses. Die Eingabedaten dieses Batch-Jobs werden aus einer Datenquelle gelesen und in StudentDTO umgewandelt Objekte. Die StudentDTO Klasse enthält die Informationen eines einzelnen Schülers und ihr Quellcode sieht wie folgt aus:

public class StudentDTO {
  
    private String emailAddress;
    private String name;
    private String purchasedPackage;
  
    public StudentDTO() {}
  
    public String getEmailAddress() {
        return emailAddress;
    }
  
    public String getName() {
        return name;
    }
  
    public String getPurchasedPackage() {
        return purchasedPackage;
    }
  
    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }
  
    public void setName(String name) {
        this.name = name;
    }
  
    public void setPurchasedPackage(String purchasedPackage) {
        this.purchasedPackage = purchasedPackage;
    }
}

In diesem Blogbeitrag schreiben Sie die Ausgabedaten Ihres Batch-Jobs in eine CSV-Datei. Genauer gesagt muss diese CSV-Datei diese Anforderungen erfüllen:

  • Als Trennzeichen muss ein Semikolon (‘;’) verwendet werden.
  • Jede Zeile muss die folgenden Informationen enthalten:den Namen des Schülers, die E-Mail-Adresse des Schülers und den Namen des gekauften Pakets.
  • Die erstellte CSV-Datei muss eine Kopfzeile haben, die die folgende Zeichenfolge enthält:'NAME;EMAIL_ADDRESS;PAKET'.

Mit anderen Worten, die CSV-Datei, die die verarbeiteten Schülerinformationen enthält, muss wie folgt aussehen:

NAME;EMAIL_ADDRESS;PACKAGE
Tony Tester;[email protected];master
Nick Newbie;[email protected];starter
Ian Intermediate;[email protected];intermediate

Als Nächstes erfahren Sie, wie Sie der erstellten CSV-Datei eine Kopfzeile hinzufügen.

Hinzufügen einer Kopfzeile zur erstellten CSV-Datei

Wenn Sie der erstellten CSV-Datei eine Kopfzeile hinzufügen möchten, müssen Sie eine benutzerdefinierte Klasse schreiben, die den FlatFileHeaderCallback implementiert Schnittstelle. Sie können diese Klasse erstellen, indem Sie diesen Schritten folgen:

  1. Erstellen Sie eine Klasse, die den FlatFileHeaderCallback implementiert Schnittstelle.
  2. Fügen Sie private hinzu und final Feld namens header zur erstellten Klasse. Dieses Feld enthält den Header, der in die erste Zeile der erstellten CSV-Datei geschrieben wird.
  3. Erstellen Sie einen Konstruktor, der den Wert von header einfügt -Feld mithilfe der Konstruktorinjektion.
  4. Überschreiben Sie den writeHeader(Writer writer) Methode des FlatFileHeaderCallback Schnittstelle.
  5. Schreiben Sie den Header in die erstellte CSV-Datei, indem Sie den Writer verwenden Objekt, das an writeHeader() übergeben wird method als Methodenparameter.

Nachdem Sie den FlatFileHeaderCallback implementiert haben Schnittstelle, der Quellcode des StringHeaderWriter Klasse sieht wie folgt aus:

import org.springframework.batch.item.file.FlatFileHeaderCallback;

import java.io.IOException;
import java.io.Writer;

public class StringHeaderWriter implements FlatFileHeaderCallback {

    private final String header;

    StringHeaderWriter(String header) {
        this.header = header;
    }

    @Override
    public void writeHeader(Writer writer) throws IOException {
        writer.write(header);
    }
}

Lassen Sie uns weitermachen und herausfinden, wie Sie die Ausgabedaten Ihres Batch-Jobs in eine CSV-Datei schreiben können.

Schreiben von Informationen in eine CSV-Datei

Wenn Sie die Ausgabedaten Ihres Batch-Jobs verarbeiten möchten, müssen Sie einen ItemWriter konfigurieren Bohne. Da Sie die Ausgabedaten in eine CSV-Datei schreiben müssen, müssen Sie diese Bean folgendermaßen konfigurieren:

Zuerst müssen Sie die Konfigurationsklasse erstellen, die die Beans enthält, die den Workflow Ihres Spring Batch-Jobs beschreiben. Der Quellcode Ihrer Konfigurationsklasse sieht wie folgt aus:

import org.springframework.context.annotation.Configuration;
  
@Configuration
public class SpringBatchExampleJobConfig {
}

Zweite , müssen Sie einen FieldExtractor<T> erstellen Objekt, das die Feldwerte aus dem Objekt extrahiert, das in eine CSV-Datei geschrieben wird. Wenn Sie einen neuen FieldExtractor<T> erstellen -Objekt müssen Sie einen Typparameter angeben, der den Typ des Objekts angibt, das die Eingabedaten Ihres ItemWriter enthält .

Sie können dieses Objekt erstellen, indem Sie diesen Schritten folgen:

  1. Fügen Sie einen private hinzu -Methode zu Ihrer Konfigurationsklasse und stellen Sie sicher, dass diese Methode einen FieldExtractor<StudentDTO> zurückgibt Objekt.
  2. Stellen Sie sicher, dass diese Methode einen BeanWrapperFieldExtractor<StudentDTO> zurückgibt Objekt. Wenn Sie einen neuen BeanWrapperFieldExtractor<StudentDTO> erstellen -Objekt müssen Sie die Eigenschaftsnamen der Eigenschaften angeben, die in die erstellte CSV-Datei geschrieben werden.

Nachdem Sie die Methode implementiert haben, die einen neuen FieldExtractor<T> zurückgibt -Objekt sieht der Quellcode Ihrer Konfigurationsklasse wie folgt aus:

import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor;
import org.springframework.batch.item.file.transform.FieldExtractor;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringBatchExampleJobConfig {

    private FieldExtractor<StudentDTO> createStudentFieldExtractor() {
        BeanWrapperFieldExtractor<StudentDTO> extractor =
                new BeanWrapperFieldExtractor<>();
        extractor.setNames(new String[] {
                "name", 
                "emailAddress", 
                "purchasedPackage"
        });
        return extractor;
    }
}

Dritter , müssen Sie einen neuen LineAggregator<T> erstellen Objekt, das die Zeile erstellt, die in die Zieldatei geschrieben wird. Wenn Sie einen neuen LineAggregator<T> erstellen -Objekt müssen Sie einen Typparameter angeben, der den Objekttyp angibt, der die Eingabedaten Ihres ItemWriter enthält .

Wenn Sie dieses Objekt erstellen möchten, sollten Sie einen neuen private hinzufügen -Methode zu Ihrer Konfigurationsklasse und stellen Sie sicher, dass diese Methode einen LineAggregator<StudentDTO> zurückgibt Objekt. Nachdem Sie diese Methode zu Ihrer Konfigurationsklasse hinzugefügt haben, sollten Sie sie folgendermaßen implementieren:

  1. Erstellen Sie einen neuen DelimitedLineAggregator<StudentDTO> Objekt. Dieses Objekt wandelt das Eingabeobjekt in einen String um Objekt, das die Eigenschaftswerte enthält, die mit dem konfigurierten FieldExtractor<StudentDTO> bereitgestellt werden Objekt. Diese Eigenschaftswerte werden durch das angegebene Trennzeichen getrennt.
  2. Konfigurieren Sie das verwendete Trennzeichen (';').
  3. Stellen Sie sicher, dass der erstellte DelimitedLineAggregator<StudentDTO> Objekt Objekt verwendet den FieldExtractor<StudentDTO> Objekt, das von createStudentFieldExtractor() zurückgegeben wird Methode.
  4. Gib den erstellten DelimitedLineAggregator<StudentDTO> zurück Objekt.

Nachdem Sie die Methode geschrieben haben, die einen neuen LineAggregator<StudentDTO> erstellt -Objekt sieht der Quellcode Ihrer Konfigurationsklasse wie folgt aus:

import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor;
import org.springframework.batch.item.file.transform.DelimitedLineAggregator;
import org.springframework.batch.item.file.transform.FieldExtractor;
import org.springframework.batch.item.file.transform.LineAggregator;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringBatchExampleJobConfig {

    private LineAggregator<StudentDTO> createStudentLineAggregator() {
        DelimitedLineAggregator<StudentDTO> lineAggregator =
                new DelimitedLineAggregator<>();
        lineAggregator.setDelimiter(";");

        FieldExtractor<StudentDTO> fieldExtractor = createStudentFieldExtractor();
        lineAggregator.setFieldExtractor(fieldExtractor);

        return lineAggregator;
    }

    private FieldExtractor<StudentDTO> createStudentFieldExtractor() {
        BeanWrapperFieldExtractor<StudentDTO> extractor =
                new BeanWrapperFieldExtractor<>();
        extractor.setNames(new String[] {
                "name", 
                "emailAddress", 
                "purchasedPackage"
        });
        return extractor;
    }
}

Vierter müssen Sie die Methode erstellen, die Ihren ItemWriter konfiguriert Bohne. Stellen Sie sicher, dass die erstellte Methode einen Environment akzeptiert Objekt als Methodenparameter und gibt einen ItemWriter<StudentDTO> zurück Objekt.

Nachdem Sie diese Methode zu Ihrer Konfigurationsklasse hinzugefügt haben, sieht ihr Quellcode wie folgt aus:

import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor;
import org.springframework.batch.item.file.transform.DelimitedLineAggregator;
import org.springframework.batch.item.file.transform.FieldExtractor;
import org.springframework.batch.item.file.transform.LineAggregator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
public class SpringBatchExampleJobConfig {

    @Bean
    public ItemWriter<StudentDTO> itemWriter(Environment environment) {

    }

    private LineAggregator<StudentDTO> createStudentLineAggregator() {
        DelimitedLineAggregator<StudentDTO> lineAggregator = 
                new DelimitedLineAggregator<>();
        lineAggregator.setDelimiter(";");

        FieldExtractor<StudentDTO> fieldExtractor = createStudentFieldExtractor();
        lineAggregator.setFieldExtractor(fieldExtractor);

        return lineAggregator;
    }

    private FieldExtractor<StudentDTO> createStudentFieldExtractor() {
        BeanWrapperFieldExtractor<StudentDTO> extractor 
                = new BeanWrapperFieldExtractor<>();
        extractor.setNames(new String[] {
                "name", 
                "emailAddress", 
                "purchasedPackage"
        });
        return extractor;
    }
}

Fünfter , müssen Sie den itemWriter() implementieren Methode, indem Sie diesen Schritten folgen:

  1. Erstellen Sie einen neuen FlatFileItemWriterBuilder<StudentDTO> Objekt. Dieses Objekt erzeugt FlatFileItemWriter<StudentDTO> Objekte, die die Ausgabedaten Ihres Batch-Jobs in eine CSV-Datei schreiben können.
  2. Konfigurieren Sie den Namen des ItemWriter .
  3. Stellen Sie sicher, dass der erstellte FlatFileItemWriter<StudentDTO> Objekt schreibt eine Kopfzeile in die erstellte CSV-Datei, indem es den StringHeaderWriter verwendet Klasse. Sie können die Kopfzeile aus einer Eigenschaftendatei lesen, indem Sie den Environment verwenden Objekt als Methodenparameter angegeben.
  4. Konfigurieren Sie den LineAggregator Objekt, das die Zeilen konstruiert, die in die erstellte CSV-Datei geschrieben werden.
  5. Konfigurieren Sie den Dateipfad der erstellten CSV-Datei. Sie können diese Informationen aus einer Eigenschaftendatei lesen, indem Sie den Environment verwenden Objekt als Methodenparameter angegeben.
  6. Erstellen Sie einen neuen FlatFileItemWriter<StudentDTO> Objekt und gibt das erstellte Objekt zurück.

Nachdem Sie den itemWriter() implementiert haben -Methode sieht der Quellcode Ihrer Konfigurationsklasse wie folgt aus:

import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.builder.FlatFileItemWriterBuilder;
import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor;
import org.springframework.batch.item.file.transform.DelimitedLineAggregator;
import org.springframework.batch.item.file.transform.FieldExtractor;
import org.springframework.batch.item.file.transform.LineAggregator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

@Configuration
public class SpringBatchExampleJobConfig {

    @Bean
    public ItemWriter<StudentDTO> itemWriter(Environment environment) {
        String exportFilePath = environment
                .getRequiredProperty("batch.job.export.file.path");
        Resource exportFileResource = new FileSystemResource(exportFilePath);

        String exportFileHeader =
                environment.getRequiredProperty("batch.job.export.file.header");
        StringHeaderWriter headerWriter = new StringHeaderWriter(exportFileHeader);

        LineAggregator<StudentDTO> lineAggregator = createStudentLineAggregator();

        return new FlatFileItemWriterBuilder<StudentDTO>()
                .name("studentWriter")
                .headerCallback(headerWriter)
                .lineAggregator(lineAggregator)
                .resource(exportFileResource)
                .build();
    }

    private LineAggregator<StudentDTO> createStudentLineAggregator() {
        DelimitedLineAggregator<StudentDTO> lineAggregator
                = new DelimitedLineAggregator<>();
        lineAggregator.setDelimiter(";");

        FieldExtractor<StudentDTO> fieldExtractor
                = createStudentFieldExtractor();
        lineAggregator.setFieldExtractor(fieldExtractor);

        return lineAggregator;
    }

    private FieldExtractor<StudentDTO> createStudentFieldExtractor() {
        BeanWrapperFieldExtractor<StudentDTO> extractor = 
                new BeanWrapperFieldExtractor<>();
        extractor.setNames(new String[] {
                "name",
                "emailAddress",
                "purchasedPackage"
        });
        return extractor;
    }
}

Sie können jetzt einen ItemWriter konfigurieren Bean, die die Ausgabedaten Ihres Batch-Jobs in eine CSV-Datei schreibt. Fassen wir zusammen, was Sie aus diesem Blogbeitrag gelernt haben.

Zusammenfassung

Dieser Blogbeitrag hat Ihnen vier Dinge beigebracht:

  • Wenn Sie die Ausgabedaten Ihres Batch-Jobs in eine CSV-Datei schreiben müssen, müssen Sie den FlatFileItemWriter<T> verwenden Klasse.
  • Wenn Sie der erstellten CSV-Datei eine Kopfzeile hinzufügen müssen, müssen Sie den FlatFileHeaderCallback implementieren Schnittstelle.
  • Der FlatFileItemWriter<T> Klasse wandelt die Eingabeobjekte in Zeilen um, die mit einem LineAggregator<T> in die CSV-Datei geschrieben werden Objekt.
  • Der DelimitedLineAggregator<T> Die Klasse extrahiert die Eigenschaftswerte aus dem verarbeiteten Objekt mithilfe von FieldExtractor<T> Objekt.

Der nächste Teil dieses Tutorials beschreibt, wie Sie die Ausgabedaten Ihres Batch-Jobs in eine XML-Datei schreiben können.


Java-Tag