1. введение
В этом коротком уроке мы увидим, как использовать Jackson для преобразования JSON в CSV и наоборот.
Существуют альтернативные библиотеки, такие как класс CDL из org.json , но здесь мы просто сосредоточимся на библиотеке Джексона.
После того, как мы рассмотрим наш пример структуры данных, мы будем использовать комбинацию ObjectMapper и CSVMapper для преобразования между JSON и CSV.
2. Зависимости
Давайте добавим зависимость для форматирования данных CSV Jackson:
com.fasterxml.jackson.dataformat jackson-dataformat-csv 2.11.1
Мы всегда можем найти самую последнюю версию этой зависимости в Maven Central .
Мы также добавим зависимость для основной базы данных Джексона:
com.fasterxml.jackson.core jackson-databind 2.11.1
Опять же, мы можем найти самую последнюю версию этой зависимости в Maven Central .
3. Структура данных
Прежде чем мы переформатируем документ JSON в CSV, нам нужно рассмотреть, насколько хорошо наша модель данных будет сопоставляться между этими двумя форматами.
Итак, сначала давайте рассмотрим, какие данные поддерживают различные форматы:
- Мы используем JSON для представления различных структур объектов, в том числе содержащих массивы и вложенные объекты
- Мы используем CSV для представления данных из списка объектов, причем каждый объект из списка появляется в новой строке
Это означает, что если наш документ JSON содержит массив объектов, мы можем переформатировать каждый объект в новую строку вашего CSV-файла. Итак, в качестве примера давайте используем документ JSON, содержащий следующий список элементов из заказа:
[ { "item" : "No. 9 Sprockets", "quantity" : 12, "unitPrice" : 1.23 }, { "item" : "Widget (10mm)", "quantity" : 4, "unitPrice" : 3.45 } ]
Мы будем использовать имена полей из документа JSON в качестве заголовков столбцов и переформатируем его в следующий CSV-файл:
item,quantity,unitPrice "No. 9 Sprockets",12,1.23 "Widget (10mm)",4,3.45
4. Чтение JSON и запись CSV
Во-первых, мы используем ObjectMapper Джексона для чтения нашего примера документа JSON в дерево JsonNode объектов:
JsonNode jsonTree = new ObjectMapper().readTree(new File("src/main/resources/orderLines.json"));
Далее давайте создадим схему Csv . Это определяет заголовки столбцов, типы и последовательность столбцов в файле CSV. Для этого мы создаем конструктор схем Csv и устанавливаем заголовки столбцов в соответствии с именами полей JSON:
Builder csvSchemaBuilder = CsvSchema.builder(); JsonNode firstObject = jsonTree.elements().next(); firstObject.fieldNames().forEachRemaining(fieldName -> {csvSchemaBuilder.addColumn(fieldName);} ); CsvSchema csvSchema = csvSchemaBuilder.build().withHeader();
Затем мы создаем CsvMapper с помощью нашей CsvSchema и, наконец , записываем дерево json в ваш CSV-файл :
CsvMapper csvMapper = new CsvMapper(); csvMapper.writerFor(JsonNode.class) .with(csvSchema) .writeValue(new File("src/main/resources/orderLines.csv"), jsonTree);
Когда мы запускаем этот пример кода, наш пример документа JSON преобразуется в ожидаемый файл CSV.
5. Чтение CSV и запись JSON
Теперь давайте воспользуемся CsvMapper Джексона, чтобы прочитать наш CSV-файл в Список объектов |/OrderLine . Для этого мы сначала создадим класс OrderLine в виде простого POJO:
public class OrderLine { private String item; private int quantity; private BigDecimal unitPrice; // Constructors, Getters, Setters and toString }
Мы будем использовать заголовки столбцов в CSV-файле для определения нашей CsvSchema . Затем мы используем CsvMapper для чтения данных из CSV в MappingIterator объектов OrderLine :
CsvSchema orderLineSchema = CsvSchema.emptySchema().withHeader(); CsvMapper csvMapper = new CsvMapper(); MappingIteratororderLines = csvMapper.readerFor(OrderLine.class) .with(orderLineSchema) .readValues(new File("src/main/resources/orderLines.csv"));
Далее мы будем использовать MappingIterator для получения Списка объектов |/OrderLine . Затем мы используем ObjectMapper Джексона, чтобы записать список в виде документа JSON:
new ObjectMapper() .configure(SerializationFeature.INDENT_OUTPUT, true) .writeValue(new File("src/main/resources/orderLinesFromCsv.json"), orderLines.readAll());
Когда мы запускаем этот пример кода, наш пример CSV-файла преобразуется в ожидаемый документ JSON.
6. Настройка формата файла CSV
Давайте воспользуемся некоторыми аннотациями Джексона, чтобы настроить формат CSV-файла. Мы изменим заголовок столбца ‘item’ на ‘name’ , заголовок столбца ‘quantity’ на ‘count’ , удалим столбец ‘UnitPrice’ и сделаем ‘count’ первым столбцом.
Итак, наш ожидаемый CSV-файл становится:
count,name 12,"No. 9 Sprockets" 4,"Widget (10mm)"
Мы создадим новый абстрактный класс, чтобы определить необходимый формат для файла CSV:
@JsonPropertyOrder({ "count", "name" }) public abstract class OrderLineForCsv { @JsonProperty("name") private String item; @JsonProperty("count") private int quantity; @JsonIgnore private BigDecimal unitPrice; }
Затем мы используем нашу строку заказа Для Csv класса для создания схемы Csv :
CsvMapper csvMapper = new CsvMapper(); CsvSchema csvSchema = csvMapper .schemaFor(OrderLineForCsv.class) .withHeader();
Мы также используем Строку Заказа Для Csv в качестве Микширования Джексона. Это говорит Джексону использовать аннотации, которые мы добавили в строку заказа Для класса Csv , когда он обрабатывает Строку заказа объект:
csvMapper.addMixIn(OrderLine.class, OrderLineForCsv.class);
Наконец, мы используем ObjectMapper для чтения вашего документа JSON в Строку заказа массив и используем наш csvMapper для записи этого в файл 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);
Когда мы запускаем этот пример кода, наш пример документа JSON преобразуется в ожидаемый файл CSV.
7. Заключение
В этом кратком руководстве мы узнали, как читать и записывать CSV-файлы с помощью библиотеки форматов данных Джексона. Мы также рассмотрели несколько вариантов конфигурации, которые помогут нам сделать наши данные такими, какими мы хотим.
Как всегда, код можно найти на GitHub .