BAEL-2922 Add Json to CSV code using Jackson CsvMapper (#7115)
This commit is contained in:
parent
d7c857266b
commit
a057010fed
@ -28,6 +28,13 @@
|
|||||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||||
<version>2.9.8</version>
|
<version>2.9.8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- CSV -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-csv</artifactId>
|
||||||
|
<version>2.9.8</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Allow use of LocalDate -->
|
<!-- Allow use of LocalDate -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.baeldung.jackson.csv;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.baeldung.jackson.entities.OrderLine;
|
||||||
|
import com.baeldung.jackson.mixin.OrderLineForCsv;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.MappingIterator;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
|
||||||
|
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
|
||||||
|
import com.fasterxml.jackson.dataformat.csv.CsvSchema.Builder;
|
||||||
|
|
||||||
|
public class JsonCsvConverter {
|
||||||
|
|
||||||
|
public static void JsonToCsv(File jsonFile, File csvFile) throws IOException {
|
||||||
|
JsonNode jsonTree = new ObjectMapper().readTree(jsonFile);
|
||||||
|
|
||||||
|
Builder csvSchemaBuilder = CsvSchema.builder();
|
||||||
|
JsonNode firstObject = jsonTree.elements().next();
|
||||||
|
firstObject.fieldNames().forEachRemaining(fieldName -> {csvSchemaBuilder.addColumn(fieldName);} );
|
||||||
|
CsvSchema csvSchema = csvSchemaBuilder
|
||||||
|
.build()
|
||||||
|
.withHeader();
|
||||||
|
|
||||||
|
CsvMapper csvMapper = new CsvMapper();
|
||||||
|
csvMapper.writerFor(JsonNode.class)
|
||||||
|
.with(csvSchema)
|
||||||
|
.writeValue(csvFile, jsonTree);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void csvToJson(File csvFile, File jsonFile) throws IOException {
|
||||||
|
CsvSchema orderLineSchema = CsvSchema.emptySchema().withHeader();
|
||||||
|
CsvMapper csvMapper = new CsvMapper();
|
||||||
|
MappingIterator<OrderLine> orderLines = csvMapper.readerFor(OrderLine.class)
|
||||||
|
.with(orderLineSchema)
|
||||||
|
.readValues(csvFile);
|
||||||
|
|
||||||
|
new ObjectMapper()
|
||||||
|
.configure(SerializationFeature.INDENT_OUTPUT, true)
|
||||||
|
.writeValue(jsonFile, orderLines.readAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void JsonToFormattedCsv(File jsonFile, File csvFile) throws IOException {
|
||||||
|
CsvMapper csvMapper = new CsvMapper();
|
||||||
|
CsvSchema csvSchema = csvMapper
|
||||||
|
.schemaFor(OrderLineForCsv.class)
|
||||||
|
.withHeader();
|
||||||
|
csvMapper.addMixIn(OrderLine.class, OrderLineForCsv.class);
|
||||||
|
|
||||||
|
OrderLine[] orderLines = new ObjectMapper()
|
||||||
|
.readValue(jsonFile, OrderLine[].class);
|
||||||
|
csvMapper.writerFor(OrderLine[].class)
|
||||||
|
.with(csvSchema)
|
||||||
|
.writeValue(csvFile, orderLines);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.jackson.mixin;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||||
|
|
||||||
|
@JsonPropertyOrder({
|
||||||
|
"count",
|
||||||
|
"name"
|
||||||
|
})
|
||||||
|
public abstract class OrderLineForCsv {
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
private String item;
|
||||||
|
|
||||||
|
@JsonProperty("count")
|
||||||
|
private int quantity;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private BigDecimal unitPrice;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
3
jackson-2/src/main/resources/orderLines.csv
Normal file
3
jackson-2/src/main/resources/orderLines.csv
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
item,quantity,unitPrice
|
||||||
|
"No. 9 Sprockets",12,1.23
|
||||||
|
"Widget (10mm)",4,3.45
|
|
9
jackson-2/src/main/resources/orderLines.json
Normal file
9
jackson-2/src/main/resources/orderLines.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[ {
|
||||||
|
"item" : "No. 9 Sprockets",
|
||||||
|
"quantity" : 12,
|
||||||
|
"unitPrice" : 1.23
|
||||||
|
}, {
|
||||||
|
"item" : "Widget (10mm)",
|
||||||
|
"quantity" : 4,
|
||||||
|
"unitPrice" : 3.45
|
||||||
|
} ]
|
@ -0,0 +1,54 @@
|
|||||||
|
package com.baeldung.jackson.csv;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParseException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
|
||||||
|
|
||||||
|
public class CsvUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenJsonInput_thenWriteCsv() throws JsonParseException, JsonMappingException, IOException {
|
||||||
|
JsonCsvConverter.JsonToCsv(new File("src/main/resources/orderLines.json"),
|
||||||
|
new File("src/main/resources/csvFromJson.csv"));
|
||||||
|
|
||||||
|
assertEquals(readFile("src/main/resources/csvFromJson.csv"),
|
||||||
|
readFile("src/test/resources/expectedCsvFromJson.csv"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCsvInput_thenWritesJson() throws JsonParseException, JsonMappingException, IOException {
|
||||||
|
JsonCsvConverter.csvToJson(new File("src/main/resources/orderLines.csv"),
|
||||||
|
new File("src/main/resources/jsonFromCsv.json"));
|
||||||
|
|
||||||
|
assertEquals(readFile("src/main/resources/jsonFromCsv.json"),
|
||||||
|
readFile("src/test/resources/expectedJsonFromCsv.json"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenJsonInput_thenWriteFormattedCsvOutput() throws JsonParseException, JsonMappingException, IOException {
|
||||||
|
JsonCsvConverter.JsonToFormattedCsv(new File("src/main/resources/orderLines.json"),
|
||||||
|
new File("src/main/resources/formattedCsvFromJson.csv"));
|
||||||
|
|
||||||
|
assertEquals(readFile("src/main/resources/formattedCsvFromJson.csv"),
|
||||||
|
readFile("src/test/resources/expectedFormattedCsvFromJson.csv"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> readFile(String filename) throws IOException {
|
||||||
|
return Files.readLines(new File(filename), Charset.forName("utf-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
;
|
3
jackson-2/src/test/resources/expectedCsvFromJson.csv
Normal file
3
jackson-2/src/test/resources/expectedCsvFromJson.csv
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
item,quantity,unitPrice
|
||||||
|
"No. 9 Sprockets",12,1.23
|
||||||
|
"Widget (10mm)",4,3.45
|
|
@ -0,0 +1,3 @@
|
|||||||
|
count,name
|
||||||
|
12,"No. 9 Sprockets"
|
||||||
|
4,"Widget (10mm)"
|
|
9
jackson-2/src/test/resources/expectedJsonFromCsv.json
Normal file
9
jackson-2/src/test/resources/expectedJsonFromCsv.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[ {
|
||||||
|
"item" : "No. 9 Sprockets",
|
||||||
|
"quantity" : 12,
|
||||||
|
"unitPrice" : 1.23
|
||||||
|
}, {
|
||||||
|
"item" : "Widget (10mm)",
|
||||||
|
"quantity" : 4,
|
||||||
|
"unitPrice" : 3.45
|
||||||
|
} ]
|
Loading…
x
Reference in New Issue
Block a user