Konvertering af JSON til CSV i Java

1. Introduktion

I denne korte vejledning ser vi, hvordan man bruger Jackson til at konvertere JSON til CSV og omvendt.

Der er alternative biblioteker tilgængelige, som CDL-klassen fra org.json, men vi fokuserer bare på Jackson-biblioteket her.

Når vi har set på vores eksempler på datastruktur, bruger vi en kombination af ObjectMapper og CSVMapper til at konvertere mellem JSON og CSV.

2. Afhængigheder

Lad os tilføje afhængigheden af ​​Jackson CSV-dataformater:

 com.fasterxml.jackson.dataformat jackson-dataformat-csv 2.11.1 

Vi kan altid finde den nyeste version af denne afhængighed af Maven Central.

Vi tilføjer også afhængigheden af ​​den centrale Jackson-databind:

 com.fasterxml.jackson.core jackson-databind 2.11.1 

Igen kan vi finde den nyeste version af denne afhængighed af Maven Central.

3. Datastruktur

Før vi omformaterer et JSON-dokument til CSV, skal vi overveje, hvor godt vores datamodel vil kortlægges mellem de to formater.

Så lad os først overveje, hvilke data de forskellige formater understøtter:

  • Vi bruger JSON til at repræsentere en række objektstrukturer, herunder dem, der indeholder arrays og indlejrede objekter
  • Vi bruger CSV til at repræsentere data fra en liste over objekter, hvor hvert objekt fra listen vises på en ny linje

Dette betyder, at hvis vores JSON-dokument har en række objekter, kan vi omformatere hvert objekt til en ny linje i vores CSV-fil. Så lad os som et eksempel bruge et JSON-dokument, der indeholder følgende liste over varer fra en ordre:

[{"item": "No. 9 tandhjul", "antal": 12, "unitPrice": 1.23}, {"item": "Widget (10mm)", "antal": 4, "unitPrice": 3.45} ]

Vi bruger feltnavne fra JSON-dokumentet som kolonneoverskrifter og omformaterer det til følgende CSV-fil:

vare, antal, enhed Pris "Nr. 9 tandhjul", 12,1,23 "Widget (10 mm)", 4,3,45

4. Læs JSON og skriv CSV

Først bruger vi Jacksons ObjectMapper at læse vores eksempel på JSON-dokument i et træ af JsonNode genstande:

JsonNode jsonTree = ny ObjectMapper (). ReadTree (ny fil ("src / main / resources / orderLines.json"));

Lad os derefter oprette en CsvSchema. Dette bestemmer kolonneoverskrifter, typer og rækkefølge af kolonner i CSV-filen. For at gøre dette opretter vi en CsvSchema Builder og indstil kolonneoverskrifterne til at matche JSON-feltnavne:

Builder csvSchemaBuilder = CsvSchema.builder (); JsonNode firstObject = jsonTree.elements (). Næste (); firstObject.fieldNames (). forEachRemaining (fieldName -> {csvSchemaBuilder.addColumn (fieldName);}); CsvSchema csvSchema = csvSchemaBuilder.build (). WithHeader ();

Derefter opretter vi en CsvMapper med vores CsvSchemaog til sidst skriver vi jsonTree til vores CSV-fil:

CsvMapper csvMapper = ny CsvMapper (); csvMapper.writerFor (JsonNode.class) .med (csvSchema) .writeValue (ny fil ("src / main / resources / orderLines.csv"), jsonTree);

Når vi kører denne eksempelkode, konverteres vores eksempel JSON-dokument til den forventede CSV-fil.

5. Læs CSV og skriv JSON

Lad os nu bruge Jacksons CsvMapper at læse vores CSV-fil i en Liste af OrderLine genstande. For at gøre dette opretter vi først OrderLine klasse som en simpel POJO:

offentlig klasse OrderLine {privat strengemne; privat int mængde; privat BigDecimal enhedPris; // Konstruktører, Getters, Setters og toString}

Vi bruger kolonneoverskrifterne i CSV-filen til at definere vores CsvSchema. Derefter, vi bruger CsvMapper at læse dataene fra CSV ind i en MappingIterator af OrderLine genstande:

CsvSchema orderLineSchema = CsvSchema.emptySchema (). WithHeader (); CsvMapper csvMapper = ny CsvMapper (); MappingIterator orderLines = csvMapper.readerFor (OrderLine.class) .med (orderLineSchema) .readValues ​​(ny fil ("src / main / resources / orderLines.csv"));

Dernæst bruger vi MappingIterator at få en Liste af OrderLine genstande. Så bruger vi Jacksons ObjectMapper at skrive listen ud som et JSON-dokument:

new ObjectMapper () .configure (SerializationFeature.INDENT_OUTPUT, true) .writeValue (new File ("src / main / resources / orderLinesFromCsv.json"), orderLines.readAll ());

Når vi kører denne eksempelkode, konverteres vores eksempel CSV-fil til det forventede JSON-dokument.

6. Konfiguration af CSV-filformat

Lad os bruge nogle af Jacksons kommentarer til at justere formatet på CSV-filen. Vi ændrer 'vare' kolonneoverskrift til 'navn', det 'antal' kolonneoverskrift til 'tælle', Fjern 'pris per stk' kolonne og lav 'tælle' den første kolonne.

Så vores forventede CSV-fil bliver:

tælle, navn 12, "Nr. 9 tandhjul" 4, "Widget (10 mm)"

Vi opretter en ny abstrakt klasse for at definere det krævede format til CSV-filen:

@JsonPropertyOrder ({"count", "name"}) offentlig abstrakt klasse OrderLineForCsv {@JsonProperty ("name") privat String element; @JsonProperty ("count") privat int-mængde; @JsonIgnorer privat BigDecimal unitPrice; }

Derefter bruger vi vores OrderLineForCsv klasse for at oprette en CsvSchema:

CsvMapper csvMapper = ny CsvMapper (); CsvSchema csvSchema = csvMapper .schemaFor (OrderLineForCsv.class) .withHeader (); 

Vi bruger også OrderLineForCsv som en Jackson Mixin. Dette fortæller Jackson at bruge de kommentarer, vi tilføjede til OrderLineForCsv klasse, når den behandler en OrderLine objekt:

csvMapper.addMixIn (OrderLine.class, OrderLineForCsv.class); 

Endelig bruger vi en ObjectMapper at læse vores JSON-dokument i et OrderLine array, og brug vores csvMapper at skrive dette til en CSV-fil:

OrderLine [] orderLines = new ObjectMapper () .readValue (new File ("src / main / resources / orderLines.json"), OrderLine []. Class); csvMapper.writerFor (OrderLine []. class) .with (csvSchema) .writeValue (new File ("src / main / resources / orderLinesReformated.csv"), orderLines); 

Når vi kører denne prøvekode, konverteres vores eksempel JSON-dokument til den forventede CSV-fil.

7. Konklusion

I denne hurtige vejledning lærte vi, hvordan man læser og skriver CSV-filer ved hjælp af Jackson-dataformatbiblioteket. Vi kiggede også på et par konfigurationsindstillinger, der hjælper os med at få vores data til at se ud, som vi ønsker.

Som altid kan koden findes på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found