Konvertering av JSON til CSV i Java

1. Introduksjon

I denne korte opplæringen vil vi se hvordan du bruker Jackson til å konvertere JSON til CSV og omvendt.

Det er alternative biblioteker tilgjengelig, som CDL-klassen fra org.json, men vi fokuserer bare på Jackson-biblioteket her.

Etter at vi har sett på eksemplet på datastrukturen, bruker vi en kombinasjon av ObjectMapper og CSVMapper for å konvertere mellom JSON og CSV.

2. Avhengigheter

La oss legge til avhengigheten for Jackson CSV-dataformatering:

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

Vi kan alltid finne den nyeste versjonen av denne avhengigheten av Maven Central.

Vi vil også legge til avhengighet for kjernen Jackson databind:

 com.fasterxml.jackson.core jackson-databind 2.11.1 

Igjen kan vi finne den nyeste versjonen av denne avhengigheten av Maven Central.

3. Datastruktur

Før vi omformaterer et JSON-dokument til CSV, må vi vurdere hvor godt datamodellen vår vil kartlegge mellom de to formatene.

Så først, la oss vurdere hvilke data de forskjellige formatene støtter:

  • Vi bruker JSON til å representere en rekke objektstrukturer, inkludert de som inneholder matriser og nestede objekter
  • Vi bruker CSV til å representere data fra en liste over objekter, med hvert objekt fra listen som vises på en ny linje

Dette betyr at hvis JSON-dokumentet vårt har en rekke objekter, kan vi formatere hvert objekt til en ny linje i CSV-filen. Så, som et eksempel, la oss bruke et JSON-dokument som inneholder følgende liste over varer fra en ordre:

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

Vi bruker feltnavnene fra JSON-dokumentet som kolonneoverskrifter, og omformaterer det til følgende CSV-fil:

vare, antall, enhet Pris "Nr. 9 tannhjul", 12,1,23 "Widget (10 mm)", 4,3,45

4. Les JSON og skriv CSV

Først bruker vi Jacksons ObjectMapper å lese eksempelet vårt JSON-dokument i et tre av JsonNode gjenstander:

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

La oss deretter lage en CsvSchema. Dette bestemmer kolonneoverskriftene, typene og sekvensen til kolonnene i CSV-filen. For å gjøre dette lager vi en CsvSchema Builder og sett kolonneoverskriftene slik at de samsvarer med JSON-feltnavnene:

Bygger csvSchemaBuilder = CsvSchema.builder (); JsonNode firstObject = jsonTree.elements (). Neste (); firstObject.fieldNames (). forEachRemaining (fieldName -> {csvSchemaBuilder.addColumn (fieldName);}); CsvSchema csvSchema = csvSchemaBuilder.build (). WithHeader ();

Deretter lager vi en CsvMapper med vår CsvSchema, og til slutt skriver vi jsonTree til CSV-filen vår:

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

Når vi kjører denne eksempelkoden, konverteres vårt eksempel JSON-dokument til den forventede CSV-filen.

5. Les CSV og skriv JSON

La oss nå bruke Jacksons CsvMapper å lese CSV-filen vår i en Liste av OrderLine gjenstander. For å gjøre dette, oppretter vi først OrderLine klasse som en enkel POJO:

offentlig klasse OrderLine {privat strengvare; privat int mengde; privat BigDecimal unitPrice; // Konstruktører, Getters, Setters og toString}

Vi bruker kolonneoverskriftene i CSV-filen til å definere vår CsvSchema. Deretter, vi bruker CsvMapper for å lese dataene fra CSV inn i en MappingIterator av OrderLine gjenstander:

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

Deretter bruker vi MappingIterator å få en Liste av OrderLine gjenstander. Så bruker vi Jacksons ObjectMapper for å skrive listen ut som et JSON-dokument:

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

Når vi kjører denne eksempelkoden, konverteres vårt CSV-eksempel til det forventede JSON-dokumentet.

6. Konfigurere CSV-filformat

La oss bruke noen av Jacksons kommentarer for å justere formatet på CSV-filen. Vi endrer 'punkt' kolonneoverskrift til 'Navn', den 'mengde' kolonneoverskrift til 'telle', fjern 'enhetspris' kolonne, og lage 'telle' den første kolonnen.

Så vår forventede CSV-fil blir:

count, name 12, "No 9 Sprockets" 4, "Widget (10mm)"

Vi oppretter en ny abstrakt klasse for å definere ønsket format for CSV-filen:

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

Så bruker vi vår OrderLineForCsv klasse for å lage en CsvSchema:

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

Vi bruker også OrderLineForCsv som en Jackson Mixin. Dette forteller Jackson å bruke kommentarene vi la til i OrderLineForCsv klasse når den behandler en OrderLine gjenstand:

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

Til slutt bruker vi en ObjectMapper å lese JSON-dokumentet vårt i et OrderLine array, og bruk vår csvMapper for å 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 kjører denne eksempelkoden, konverteres vårt eksempel JSON-dokument til den forventede CSV-filen.

7. Konklusjon

I denne raske opplæringen lærte vi å lese og skrive CSV-filer ved hjelp av Jackson dataformatbibliotek. Vi så også på noen få konfigurasjonsalternativer som hjelper oss med å få dataene våre til å se ut som vi ønsker.

Som alltid kan koden bli funnet på GitHub.


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