Menukar JSON ke CSV di Java

1. Pengenalan

Dalam tutorial ringkas ini, kita akan melihat bagaimana menggunakan Jackson untuk menukar JSON menjadi CSV dan sebaliknya.

Terdapat perpustakaan alternatif yang tersedia, seperti kelas CDL dari org.json, tetapi kami hanya akan memberi tumpuan kepada perpustakaan Jackson di sini.

Setelah melihat struktur data contoh kami, kami akan menggunakan kombinasi ObjectMapper dan CSVMapper untuk menukar antara JSON dan CSV.

2. Kebergantungan

Mari tambahkan kebergantungan untuk pemformat data Jackson CSV:

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

Kita selalu dapat mencari versi terbaru dari pergantungan ini pada Maven Central.

Kami juga akan menambahkan kebergantungan untuk pangkalan data inti Jackson:

 com.fasterxml.jackson.core jackson-databind 2.11.1 

Sekali lagi, kita dapat mencari versi terbaru dari pergantungan ini pada Maven Central.

3. Struktur Data

Sebelum kita memformat ulang dokumen JSON ke CSV, kita perlu mempertimbangkan seberapa baik model data kita akan memetakan antara kedua format.

Oleh itu, mari kita pertimbangkan data apa yang disokong oleh pelbagai format:

  • Kami menggunakan JSON untuk mewakili pelbagai struktur objek, termasuk struktur yang mengandungi tatasusunan dan objek bersarang
  • Kami menggunakan CSV untuk mewakili data dari daftar objek, dengan setiap objek dari daftar muncul pada baris baru

Ini bermaksud bahawa jika dokumen JSON kami mempunyai susunan objek, kami dapat memformat ulang setiap objek menjadi baris baru file CSV kami. Jadi, sebagai contoh, mari gunakan dokumen JSON yang mengandungi senarai item berikut dari pesanan:

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

Kami akan menggunakan nama bidang dari dokumen JSON sebagai tajuk lajur, dan memformatnya semula ke fail CSV berikut:

item,quantity,unitPrice "No. 9 Sprockets",12,1.23 "Widget (10mm)",4,3.45

4. Baca JSON dan Tulis CSV

Pertama, kami menggunakan Jackson's ObjectMapper untuk membaca contoh dokumen JSON kami ke dalam pokok objek JsonNode :

JsonNode jsonTree = new ObjectMapper().readTree(new File("src/main/resources/orderLines.json"));

Seterusnya, mari buat CsvSchema . Ini menentukan tajuk lajur, jenis, dan urutan lajur dalam fail CSV. Untuk melakukan ini, kami membuat Pembangun CsvSchema dan menetapkan tajuk lajur agar sesuai dengan nama bidang JSON:

Builder csvSchemaBuilder = CsvSchema.builder(); JsonNode firstObject = jsonTree.elements().next(); firstObject.fieldNames().forEachRemaining(fieldName -> {csvSchemaBuilder.addColumn(fieldName);} ); CsvSchema csvSchema = csvSchemaBuilder.build().withHeader();

Kemudian, kita membuat CsvMapper dengan kami CsvSchema , dan akhirnya, kita menulis jsonTree ke fail CSV kami :

CsvMapper csvMapper = new CsvMapper(); csvMapper.writerFor(JsonNode.class) .with(csvSchema) .writeValue(new File("src/main/resources/orderLines.csv"), jsonTree);

Apabila kami menjalankan contoh kod ini, contoh dokumen JSON kami ditukar ke fail CSV yang diharapkan.

5. Baca CSV dan Tulis JSON

Sekarang, mari kita menggunakan Jackson CsvMapper untuk membaca fail CSV kami ke dalam List of Baris Pesanan objek. Untuk melakukan ini, kami mula-mula membuat kelas OrderLine sebagai POJO mudah:

public class OrderLine { private String item; private int quantity; private BigDecimal unitPrice; // Constructors, Getters, Setters and toString }

Kami akan menggunakan tajuk lajur dalam fail CSV untuk menentukan CsvSchema kami . Kemudian, kita menggunakan CsvMapper untuk membaca data dari CSV ke dalam MappingIterator daripada Baris Pesanan objek:

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

Seterusnya, kami akan menggunakan MappingIterator untuk mendapatkan Senarai daripada Baris Pesanan objek. Kemudian, kami menggunakan Jackson's ObjectMapper untuk menulis senarai sebagai dokumen JSON:

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

Apabila kami menjalankan contoh kod ini, contoh fail CSV kami ditukar ke dokumen JSON yang diharapkan.

6. Mengkonfigurasi Format Fail CSV

Mari gunakan beberapa anotasi Jackson untuk menyesuaikan format fail CSV. Kami akan menukar tajuk lajur 'item' menjadi 'nama' , tajuk lajur 'kuantiti' menjadi 'kiraan' , membuang lajur 'unitPrice' , dan menjadikan 'hitung' lajur pertama.

Oleh itu, fail CSV yang kami harapkan menjadi:

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

Kami akan membuat kelas abstrak baru untuk menentukan format yang diperlukan untuk fail CSV:

@JsonPropertyOrder({ "count", "name" }) public abstract class OrderLineForCsv { @JsonProperty("name") private String item; @JsonProperty("count") private int quantity; @JsonIgnore private BigDecimal unitPrice; }

Kemudian, kami menggunakan kelas OrderLineForCsv kami untuk membuat CsvSchema :

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

Kami juga menggunakan OrderLineForCsv sebagai Jackson Mixin. Ini memberitahu Jackson untuk menggunakan anotasi yang kami tambahkan ke kelas OrderLineForCsv ketika memproses objek OrderLine :

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

Akhirnya, kami menggunakan ObjectMapper untuk membaca dokumen JSON kami ke dalam array OrderLine , dan menggunakan csvMapper kami untuk menulis ini ke fail CSV:

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); 

Apabila kami menjalankan contoh kod ini, contoh dokumen JSON kami ditukar ke fail CSV yang diharapkan.

7. Kesimpulannya

Dalam tutorial ringkas ini, kami belajar membaca dan menulis fail CSV menggunakan perpustakaan format data Jackson. Kami juga melihat beberapa pilihan konfigurasi yang membantu kami mendapatkan data kami seperti yang kami mahukan.

Seperti biasa, kodnya boleh didapati di GitHub.