Update README.md

This commit is contained in:
johnA1331
2019-10-30 22:12:05 +08:00
committed by GitHub
parent db85c8f275
commit 33998bdac8
20533 changed files with 1642695 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
*.class
#folders#
/target
/neoDb*
/data
/src/main/webapp/WEB-INF/classes
*/META-INF/*
# Packaged files #
*.jar
*.war
*.ear
# Files
/src/main/resources/orderOutput.yaml
+15
View File
@@ -0,0 +1,15 @@
## Jackson Cookbooks and Examples
This module contains articles about Jackson.
### The Course
The "REST With Spring" Classes: http://bit.ly/restwithspring
### Relevant Articles:
- [Mapping Multiple JSON Fields to a Single Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field)
- [How to Process YAML with Jackson](https://www.baeldung.com/jackson-yaml)
- [Working with Tree Model Nodes in Jackson](https://www.baeldung.com/jackson-json-node-tree-model)
- [Converting JSON to CSV in Java](https://www.baeldung.com/java-converting-json-to-csv)
- [Compare Two JSON Objects with Jackson](https://www.baeldung.com/jackson-compare-two-json-objects)
- [Calling Default Serializer from Custom Serializer in Jackson](https://www.baeldung.com/jackson-call-default-serializer-from-custom-serializer)
- More articles: [[<-- prev]](/../jackson)
+73
View File
@@ -0,0 +1,73 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>jackson-2</artifactId>
<version>0.1-SNAPSHOT</version>
<name>jackson-2</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-java</relativePath>
</parent>
<dependencies>
<!-- marshalling -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- YAML -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- CSV -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-csv</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- Allow use of LocalDate -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>jackson-2</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<properties>
<!-- testing -->
<assertj.version>3.11.0</assertj.version>
</properties>
</project>
@@ -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.entities;
public class File {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -0,0 +1,82 @@
package com.baeldung.jackson.entities;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class Folder {
private Long id;
private String name;
private String owner;
private Date created;
private Date modified;
private Date lastAccess;
@JsonIgnore
private List<File> files = new ArrayList<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getModified() {
return modified;
}
public void setModified(Date modified) {
this.modified = modified;
}
public Date getLastAccess() {
return lastAccess;
}
public void setLastAccess(Date lastAccess) {
this.lastAccess = lastAccess;
}
public List<File> getFiles() {
return files;
}
public void setFiles(List<File> files) {
this.files = files;
}
}
@@ -0,0 +1,68 @@
package com.baeldung.jackson.entities;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class Order {
private String orderNo;
private LocalDate date;
private String customerName;
private List<OrderLine> orderLines;
public Order() {
}
public Order(String orderNo, LocalDate date, String customerName, List<OrderLine> orderLines) {
super();
this.orderNo = orderNo;
this.date = date;
this.customerName = customerName;
this.orderLines = orderLines;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public List<OrderLine> getOrderLines() {
if (orderLines == null) {
orderLines = new ArrayList<>();
}
return orderLines;
}
public void setOrderLines(List<OrderLine> orderLines) {
if (orderLines == null) {
orderLines = new ArrayList<>();
}
this.orderLines = orderLines;
}
@Override
public String toString() {
return "Order [orderNo=" + orderNo + ", date=" + date + ", customerName=" + customerName + ", orderLines=" + orderLines + "]";
}
}
@@ -0,0 +1,49 @@
package com.baeldung.jackson.entities;
import java.math.BigDecimal;
public class OrderLine {
private String item;
private int quantity;
private BigDecimal unitPrice;
public OrderLine() {
}
public OrderLine(String item, int quantity, BigDecimal unitPrice) {
super();
this.item = item;
this.quantity = quantity;
this.unitPrice = unitPrice;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public BigDecimal getUnitPrice() {
return unitPrice;
}
public void setUnitPrice(BigDecimal unitPrice) {
this.unitPrice = unitPrice;
}
@Override
public String toString() {
return "OrderLine [item=" + item + ", quantity=" + quantity + ", unitPrice=" + unitPrice + "]";
}
}
@@ -0,0 +1,44 @@
package com.baeldung.jackson.entities;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Weather {
@JsonProperty("location")
@JsonAlias("place")
private String location;
@JsonProperty("temp")
@JsonAlias("temperature")
private int temp;
@JsonProperty("outlook")
@JsonAlias("weather")
private String outlook;
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public int getTemp() {
return temp;
}
public void setTemp(int temp) {
this.temp = temp;
}
public String getOutlook() {
return outlook;
}
public void setOutlook(String outlook) {
this.outlook = outlook;
}
}
@@ -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;
}
@@ -0,0 +1,62 @@
package com.baeldung.jackson.node;
import java.util.Iterator;
import java.util.Map.Entry;
import com.fasterxml.jackson.databind.JsonNode;
public class JsonNodeIterator {
private static final String NEW_LINE = "\n";
private static final String FIELD_DELIMITER = ": ";
private static final String ARRAY_PREFIX = "- ";
private static final String YAML_PREFIX = " ";
public String toYaml(JsonNode root) {
StringBuilder yaml = new StringBuilder();
processNode(root, yaml, 0);
return yaml.toString();
}
private void processNode(JsonNode jsonNode, StringBuilder yaml, int depth) {
if (jsonNode.isValueNode()) {
yaml.append(jsonNode.asText());
}
else if (jsonNode.isArray()) {
for (JsonNode arrayItem : jsonNode) {
appendNodeToYaml(arrayItem, yaml, depth, true);
}
}
else if (jsonNode.isObject()) {
appendNodeToYaml(jsonNode, yaml, depth, false);
}
}
private void appendNodeToYaml(JsonNode node, StringBuilder yaml, int depth, boolean isArrayItem) {
Iterator<Entry<String, JsonNode>> fields = node.fields();
boolean isFirst = true;
while (fields.hasNext()) {
Entry<String, JsonNode> jsonField = fields.next();
addFieldNameToYaml(yaml, jsonField.getKey(), depth, isArrayItem && isFirst);
processNode(jsonField.getValue(), yaml, depth+1);
isFirst = false;
}
}
private void addFieldNameToYaml(StringBuilder yaml, String fieldName, int depth, boolean isFirstInArray) {
if (yaml.length()>0) {
yaml.append(NEW_LINE);
int requiredDepth = (isFirstInArray) ? depth-1 : depth;
for(int i = 0; i < requiredDepth; i++) {
yaml.append(YAML_PREFIX);
}
if (isFirstInArray) {
yaml.append(ARRAY_PREFIX);
}
}
yaml.append(fieldName);
yaml.append(FIELD_DELIMITER);
}
}
@@ -0,0 +1,21 @@
package com.baeldung.jackson.serialization.custom.serializer;
import com.baeldung.jackson.entities.Folder;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
public class FolderBeanSerializerModifier extends BeanSerializerModifier {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
if (beanDesc.getBeanClass().equals(Folder.class)) {
return new FolderSerializerWithDefaultSerializerStored((JsonSerializer<Object>) serializer);
}
return serializer;
}
}
@@ -0,0 +1,36 @@
package com.baeldung.jackson.serialization.custom.serializer;
import java.io.IOException;
import com.baeldung.jackson.entities.File;
import com.baeldung.jackson.entities.Folder;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
public class FolderSerializer extends StdSerializer<Folder> {
public FolderSerializer() {
super(Folder.class);
}
@Override
public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeStringField("name", value.getName());
gen.writeArrayFieldStart("files");
for (File file : value.getFiles()) {
gen.writeStartObject();
gen.writeNumberField("id", file.getId());
gen.writeStringField("name", file.getName());
gen.writeEndObject();
}
gen.writeEndArray();
gen.writeEndObject();
}
}
@@ -0,0 +1,30 @@
package com.baeldung.jackson.serialization.custom.serializer;
import java.io.IOException;
import com.baeldung.jackson.entities.Folder;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
public class FolderSerializerWithCallingOwnSerializer extends StdSerializer<Folder> {
public FolderSerializerWithCallingOwnSerializer() {
super(Folder.class);
}
@Override
public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeStringField("name", value.getName());
provider.defaultSerializeField("files", value.getFiles(), gen);
provider.defaultSerializeField("details", value, gen);
gen.writeEndObject();
}
}
@@ -0,0 +1,35 @@
package com.baeldung.jackson.serialization.custom.serializer;
import java.io.IOException;
import com.baeldung.jackson.entities.Folder;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
public class FolderSerializerWithDefaultSerializerStored extends StdSerializer<Folder> {
private final JsonSerializer<Object> defaultSerializer;
public FolderSerializerWithDefaultSerializerStored(JsonSerializer<Object> defaultSerializer) {
super(Folder.class);
this.defaultSerializer = defaultSerializer;
}
@Override
public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeStringField("name", value.getName());
provider.defaultSerializeField("files", value.getFiles(), gen);
gen.writeFieldName("details");
defaultSerializer.serialize(value, gen, provider);
gen.writeEndObject();
}
}
@@ -0,0 +1,34 @@
package com.baeldung.jackson.serialization.custom.serializer;
import java.io.IOException;
import com.baeldung.jackson.entities.Folder;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
public class FolderSerializerWithInternalObjectMapper extends StdSerializer<Folder> {
public FolderSerializerWithInternalObjectMapper() {
super(Folder.class);
}
@Override
public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeStringField("name", value.getName());
// we access internal mapper to delegate the serialization of File list
ObjectMapper mapper = (ObjectMapper) gen.getCodec();
gen.writeFieldName("files");
String stringValue = mapper.writeValueAsString(value.getFiles());
gen.writeRawValue(stringValue);
gen.writeEndObject();
}
}
@@ -0,0 +1,29 @@
package com.baeldung.jackson.serialization.custom.serializer;
import java.io.IOException;
import com.baeldung.jackson.entities.Folder;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
public class FolderSerializerWithSerializerProvider extends StdSerializer<Folder> {
public FolderSerializerWithSerializerProvider() {
super(Folder.class);
}
@Override
public void serialize(Folder value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeStringField("name", value.getName());
// we delegate the File list serialization to its default serializer
provider.defaultSerializeField("files", value.getFiles(), gen);
gen.writeEndObject();
}
}
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
@@ -0,0 +1,11 @@
orderNo: A001
date: 2019-04-17
customerName: Customer, Joe
orderLines:
- item: No. 9 Sprockets
quantity: 12
unitPrice: 1.23
- item: Widget (10mm)
quantity: 4
unitPrice: 3.45
@@ -0,0 +1,3 @@
item,quantity,unitPrice
"No. 9 Sprockets",12,1.23
"Widget (10mm)",4,3.45
1 item quantity unitPrice
2 No. 9 Sprockets 12 1.23
3 Widget (10mm) 4 3.45
@@ -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"));
}
}
;
@@ -0,0 +1,38 @@
package com.baeldung.jackson.deserialization.jsonalias;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.baeldung.jackson.entities.Weather;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonAliasUnitTest {
@Test
public void givenTwoJsonFormats_whenDeserialized_thenWeatherObjectsCreated() throws Exception {
ObjectMapper mapper = new ObjectMapper();
Weather weather = mapper.readValue("{" +
"\"location\": \"London\"," +
"\"temp\": 15," +
"\"weather\": \"Cloudy\"" +
"}", Weather.class);
assertEquals("London", weather.getLocation());
assertEquals("Cloudy", weather.getOutlook());
assertEquals(15, weather.getTemp());
weather = mapper.readValue("{" +
"\"place\": \"Lisbon\"," +
"\"temperature\": 35," +
"\"outlook\": \"Sunny\"" +
"}", Weather.class);
assertEquals("Lisbon", weather.getLocation());
assertEquals("Sunny", weather.getOutlook());
assertEquals(35, weather.getTemp());
}
}
@@ -0,0 +1,126 @@
package com.baeldung.jackson.json.compare;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.Comparator;
import org.junit.Test;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.NumericNode;
import com.fasterxml.jackson.databind.node.TextNode;
public class JsonCompareUnitTest {
@Test
public void givenTwoSameJsonDataObjects_whenCompared_thenAreEqual() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\", \"age\": 34 }}";
String s2 = "{\"employee\": {\"id\": \"1212\",\"age\": 34, \"fullName\": \"John Miles\" }}";
JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);
assertEquals(actualObj1, actualObj2);
}
@Test
public void givenTwoSameNestedJsonDataObjects_whenCompared_thenEqual() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"contact\":{\"email\": \"john@xyz.com\",\"phone\": \"9999999999\"} }}";
String s2 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"contact\":{\"email\": \"john@xyz.com\",\"phone\": \"9999999999\"} }}";
JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);
assertEquals(actualObj1, actualObj2);
}
@Test
public void givenTwoSameListJsonDataObjects_whenCompared_thenEqual() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"skills\":[\"Java\", \"C++\", \"Python\"] }}";
String s2 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"skills\":[\"Java\", \"C++\", \"Python\"] }}";
JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);
assertEquals(actualObj1, actualObj2);
}
@Test
public void givenTwoJsonDataObjects_whenComparedUsingCustomNumericNodeComparator_thenEqual() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String s1 = "{\"name\": \"John\",\"score\":5.0}";
String s2 = "{\"name\": \"John\",\"score\":5}";
JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);
NumericNodeComparator cmp = new NumericNodeComparator();
assertNotEquals(actualObj1, actualObj2);
assertTrue(actualObj1.equals(cmp, actualObj2));
}
public class NumericNodeComparator implements Comparator<JsonNode> {
@Override
public int compare(JsonNode o1, JsonNode o2) {
if (o1.equals(o2)) {
return 0;
}
if ((o1 instanceof NumericNode) && (o2 instanceof NumericNode)) {
Double d1 = ((NumericNode) o1).asDouble();
Double d2 = ((NumericNode) o2).asDouble();
if (d1.compareTo(d2) == 0) {
return 0;
}
}
return 1;
}
}
@Test
public void givenTwoJsonDataObjects_whenComparedUsingCustomTextNodeComparator_thenEqual() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String s1 = "{\"name\": \"JOHN\",\"score\":5}";
String s2 = "{\"name\": \"John\",\"score\":5}";
JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);
TextNodeComparator cmp = new TextNodeComparator();
assertNotEquals(actualObj1, actualObj2);
assertTrue(actualObj1.equals(cmp, actualObj2));
}
public class TextNodeComparator implements Comparator<JsonNode> {
@Override
public int compare(JsonNode o1, JsonNode o2) {
if (o1.equals(o2)) {
return 0;
}
if ((o1 instanceof TextNode) && (o2 instanceof TextNode)) {
String s1 = ((TextNode) o1).asText();
String s2 = ((TextNode) o2).asText();
if (s1.equalsIgnoreCase(s2)) {
return 0;
}
}
return 1;
}
}
}
@@ -0,0 +1,18 @@
package com.baeldung.jackson.node;
import java.io.IOException;
import java.io.InputStream;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ExampleStructure {
private static ObjectMapper mapper = new ObjectMapper();
static JsonNode getExampleRoot() throws IOException {
InputStream exampleInput = ExampleStructure.class.getClassLoader()
.getResourceAsStream("node_example.json");
JsonNode rootNode = mapper.readTree(exampleInput);
return rootNode;
}
}
@@ -0,0 +1,37 @@
package com.baeldung.jackson.node;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import org.junit.Test;
import com.fasterxml.jackson.databind.JsonNode;
public class JsonNodeIteratorUnitTest {
private JsonNodeIterator onTest = new JsonNodeIterator();
private static String expectedYaml = "name: \n" +
" first: Tatu\n" +
" last: Saloranta\n" +
"title: Jackson founder\n" +
"company: FasterXML\n" +
"pets: \n" +
"- type: dog\n" +
" number: 1\n" +
"- type: fish\n" +
" number: 50";
@Test
public void givenANodeTree_whenIteratingSubNodes_thenWeFindExpected() throws IOException {
final JsonNode rootNode = ExampleStructure.getExampleRoot();
String yaml = onTest.toYaml(rootNode);
System.out.println(yaml.toString());
assertEquals(expectedYaml, yaml);
}
}
@@ -0,0 +1,30 @@
package com.baeldung.jackson.node;
public class NodeBean {
private int id;
private String name;
public NodeBean() {
}
public NodeBean(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@@ -0,0 +1,119 @@
package com.baeldung.jackson.node;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class NodeOperationUnitTest {
private static ObjectMapper mapper = new ObjectMapper();
@Test
public void givenAnObject_whenConvertingIntoNode_thenCorrect() {
final NodeBean fromValue = new NodeBean(2016, "baeldung.com");
final JsonNode node = mapper.valueToTree(fromValue);
assertEquals(2016, node.get("id")
.intValue());
assertEquals("baeldung.com", node.get("name")
.textValue());
}
@Test
public void givenANode_whenWritingOutAsAJsonString_thenCorrect() throws IOException {
final String pathToTestFile = "node_to_json_test.json";
final char[] characterBuffer = new char[50];
final JsonNode node = mapper.createObjectNode();
((ObjectNode) node).put("id", 2016);
((ObjectNode) node).put("name", "baeldung.com");
try (FileWriter outputStream = new FileWriter(pathToTestFile)) {
mapper.writeValue(outputStream, node);
}
try (FileReader inputStreamForAssertion = new FileReader(pathToTestFile)) {
inputStreamForAssertion.read(characterBuffer);
}
final String textContentOfTestFile = new String(characterBuffer);
assertThat(textContentOfTestFile, containsString("2016"));
assertThat(textContentOfTestFile, containsString("baeldung.com"));
Files.delete(Paths.get(pathToTestFile));
}
@Test
public void givenANode_whenConvertingIntoAnObject_thenCorrect() throws JsonProcessingException {
final JsonNode node = mapper.createObjectNode();
((ObjectNode) node).put("id", 2016);
((ObjectNode) node).put("name", "baeldung.com");
final NodeBean toValue = mapper.treeToValue(node, NodeBean.class);
assertEquals(2016, toValue.getId());
assertEquals("baeldung.com", toValue.getName());
}
@Test
public void givenANode_whenAddingIntoATree_thenCorrect() throws IOException {
final JsonNode rootNode = ExampleStructure.getExampleRoot();
final ObjectNode addedNode = ((ObjectNode) rootNode).putObject("address");
addedNode.put("city", "Seattle")
.put("state", "Washington")
.put("country", "United States");
assertFalse(rootNode.path("address")
.isMissingNode());
assertEquals("Seattle", rootNode.path("address")
.path("city")
.textValue());
assertEquals("Washington", rootNode.path("address")
.path("state")
.textValue());
assertEquals("United States", rootNode.path("address")
.path("country")
.textValue());
}
@Test
public void givenANode_whenModifyingIt_thenCorrect() throws IOException {
final String newString = "{\"nick\": \"cowtowncoder\"}";
final JsonNode newNode = mapper.readTree(newString);
final JsonNode rootNode = ExampleStructure.getExampleRoot();
((ObjectNode) rootNode).set("name", newNode);
assertFalse(rootNode.path("name")
.path("nick")
.isMissingNode());
assertEquals("cowtowncoder", rootNode.path("name")
.path("nick")
.textValue());
}
@Test
public void givenANode_whenRemovingFromATree_thenCorrect() throws IOException {
final JsonNode rootNode = ExampleStructure.getExampleRoot();
((ObjectNode) rootNode).remove("company");
assertTrue(rootNode.path("company")
.isMissingNode());
}
}
@@ -0,0 +1,166 @@
package com.baeldung.jackson.serialization.custom.serializer;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import com.baeldung.jackson.entities.File;
import com.baeldung.jackson.entities.Folder;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
public class CallingDefaultSerializerUnitTest {
private ObjectMapper mapper;
private Folder mockFolder;
private TypeReference<HashMap<String, Object>> mapType;
@Before
public void setup() {
mapType = new TypeReference<HashMap<String, Object>>() {
};
mapper = new ObjectMapper();
mockFolder = new Folder();
mockFolder.setId(1L);
mockFolder.setName("Root Folder");
mockFolder.setOwner("root");
mockFolder.setCreated(Date.from(Instant.now().minusSeconds(60)));
mockFolder.setModified(Date.from(Instant.now().minusSeconds(30)));
mockFolder.setLastAccess(Date.from(Instant.now()));
File file1 = new File();
file1.setId(1L);
file1.setName("File 1");
File file2 = new File();
file2.setId(2L);
file2.setName("File 2");
List<File> files = new ArrayList<>();
files.add(file1);
files.add(file2);
mockFolder.setFiles(files);
}
@Test
public void givenFolder_whenSerialized_onlyNameAndFilesFieldsSerialized() throws IOException {
SimpleModule module = new SimpleModule();
module.addSerializer(new FolderSerializer());
mapper.registerModule(module);
String json = mapper.writeValueAsString(mockFolder);
HashMap<String, Object> actual = mapper.readValue(json, mapType);
assertTrue(actual.containsKey("name"));
assertTrue(actual.containsKey("files"));
assertEquals(mockFolder.getName(), actual.get("name"));
List actualFiles = (List) actual.get("files");
assertEquals(mockFolder.getFiles().size(), actualFiles.size());
}
@Test
public void givenFolder_whenSerializedWithSerializerProvider_onlyNameAndFilesFieldsSerialized() throws IOException {
SimpleModule module = new SimpleModule();
module.addSerializer(new FolderSerializerWithSerializerProvider());
mapper.registerModule(module);
String json = mapper.writeValueAsString(mockFolder);
HashMap<String, Object> actual = mapper.readValue(json, mapType);
assertTrue(actual.containsKey("name"));
assertTrue(actual.containsKey("files"));
assertEquals(mockFolder.getName(), actual.get("name"));
List actualFiles = (List) actual.get("files");
assertEquals(mockFolder.getFiles().size(), actualFiles.size());
}
@Test
public void givenFolder_whenSerializedWithInternalObjectMapper_onlyNameAndFilesFieldsSerialized() throws IOException {
SimpleModule module = new SimpleModule();
module.addSerializer(new FolderSerializerWithInternalObjectMapper());
mapper.registerModule(module);
String json = mapper.writeValueAsString(mockFolder);
HashMap<String, Object> actual = mapper.readValue(json, mapType);
assertTrue(actual.containsKey("name"));
assertTrue(actual.containsKey("files"));
assertEquals(mockFolder.getName(), actual.get("name"));
List actualFiles = (List) actual.get("files");
assertEquals(mockFolder.getFiles().size(), actualFiles.size());
}
@Test(expected = StackOverflowError.class)
public void givenFolder_whenSerializedWithCallingOwnSerializer_exceptionOccured() throws IOException {
SimpleModule module = new SimpleModule();
module.addSerializer(new FolderSerializerWithCallingOwnSerializer());
mapper.registerModule(module);
mapper.writeValueAsString(mockFolder);
}
@Test
public void givenFolder_whenSerializedWithDefaultSerializerStored_NameAndFilesAndDetailsFieldsSerialized() throws IOException {
SimpleModule module = new SimpleModule();
module.setSerializerModifier(new FolderBeanSerializerModifier());
mapper.registerModule(module);
String json = mapper.writeValueAsString(mockFolder);
HashMap<String, Object> actual = mapper.readValue(json, mapType);
assertTrue(actual.containsKey("name"));
assertTrue(actual.containsKey("files"));
assertEquals(mockFolder.getName(), actual.get("name"));
List actualFiles = (List) actual.get("files");
assertEquals(mockFolder.getFiles().size(), actualFiles.size());
Map actualDetails = (Map) actual.get("details");
assertTrue(actualDetails.containsKey("id"));
assertTrue(actualDetails.containsKey("name"));
assertTrue(actualDetails.containsKey("owner"));
assertTrue(actualDetails.containsKey("created"));
assertTrue(actualDetails.containsKey("modified"));
assertTrue(actualDetails.containsKey("lastAccess"));
assertEquals(mockFolder.getId().longValue(), ((Number)actualDetails.get("id")).longValue());
assertEquals(mockFolder.getName(), actualDetails.get("name"));
assertEquals(mockFolder.getOwner(), actualDetails.get("owner"));
assertEquals(mockFolder.getCreated(), new Date((long) actualDetails.get("created")));
assertEquals(mockFolder.getModified(), new Date((long) actualDetails.get("modified")));
assertEquals(mockFolder.getLastAccess(), new Date((long) actualDetails.get("lastAccess")));
}
}
@@ -0,0 +1,63 @@
package com.baeldung.jackson.yaml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.baeldung.jackson.entities.Order;
import com.baeldung.jackson.entities.OrderLine;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature;
public class YamlUnitTest {
private ObjectMapper mapper;
@Before
public void setup() {
mapper = new ObjectMapper(new YAMLFactory().disable(Feature.WRITE_DOC_START_MARKER));
mapper.findAndRegisterModules();
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
@Test
public void givenYamlInput_ObjectCreated() throws JsonParseException, JsonMappingException, IOException {
Order order = mapper.readValue(new File("src/main/resources/orderInput.yaml"), Order.class);
assertEquals("A001", order.getOrderNo());
assertEquals(LocalDate.parse("2019-04-17", DateTimeFormatter.ISO_DATE), order.getDate());
assertEquals("Customer, Joe", order.getCustomerName());
assertEquals(2, order.getOrderLines()
.size());
}
@Test
public void givenYamlObject_FileWritten() throws JsonGenerationException, JsonMappingException, IOException {
List<OrderLine> lines = new ArrayList<>();
lines.add(new OrderLine("Copper Wire (200ft)", 1, new BigDecimal(50.67).setScale(2, RoundingMode.HALF_UP)));
lines.add(new OrderLine("Washers (1/4\")", 24, new BigDecimal(.15).setScale(2, RoundingMode.HALF_UP)));
Order order = new Order(
"B-9910",
LocalDate.parse("2019-04-18", DateTimeFormatter.ISO_DATE),
"Customer, Jane",
lines);
mapper.writeValue(new File("src/main/resources/orderOutput.yaml"), order);
File outputYaml = new File("src/main/resources/orderOutput.yaml");
assertTrue(outputYaml.exists());
}
}
@@ -0,0 +1,3 @@
item,quantity,unitPrice
"No. 9 Sprockets",12,1.23
"Widget (10mm)",4,3.45
1 item quantity unitPrice
2 No. 9 Sprockets 12 1.23
3 Widget (10mm) 4 3.45
@@ -0,0 +1,3 @@
count,name
12,"No. 9 Sprockets"
4,"Widget (10mm)"
1 count name
2 12 No. 9 Sprockets
3 4 Widget (10mm)
@@ -0,0 +1,9 @@
[ {
"item" : "No. 9 Sprockets",
"quantity" : 12,
"unitPrice" : 1.23
}, {
"item" : "Widget (10mm)",
"quantity" : 4,
"unitPrice" : 3.45
} ]
@@ -0,0 +1,18 @@
{
"name": {
"first": "Tatu",
"last": "Saloranta"
},
"title": "Jackson founder",
"company": "FasterXML",
"pets": [
{
"type": "dog",
"number": 1
},
{
"type": "fish",
"number": 50
}
]
}