diff --git a/core-java-io/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java b/core-java-io/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java
new file mode 100644
index 0000000000..6964ba80e3
--- /dev/null
+++ b/core-java-io/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java
@@ -0,0 +1,165 @@
+package com.baeldung.filechannel;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.charset.StandardCharsets;
+
+import org.junit.Test;
+
+public class FileChannelUnitTest {
+
+ @Test
+ public void givenFile_whenReadWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException {
+
+ try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r");
+ FileChannel channel = reader.getChannel();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();) {
+
+ int bufferSize = 1024;
+ if (bufferSize > channel.size()) {
+ bufferSize = (int) channel.size();
+ }
+ ByteBuffer buff = ByteBuffer.allocate(bufferSize);
+
+ while (channel.read(buff) > 0) {
+ out.write(buff.array(), 0, buff.position());
+ buff.clear();
+ }
+
+ String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8);
+
+ assertEquals("Hello world", fileContent);
+ }
+ }
+
+ @Test
+ public void givenFile_whenReadWithFileChannelUsingFileInputStream_thenCorrect() throws IOException {
+
+ try (ByteArrayOutputStream out = new ByteArrayOutputStream();
+ FileInputStream fin = new FileInputStream("src/test/resources/test_read.in");
+ FileChannel channel = fin.getChannel();) {
+
+ int bufferSize = 1024;
+ if (bufferSize > channel.size()) {
+ bufferSize = (int) channel.size();
+ }
+ ByteBuffer buff = ByteBuffer.allocate(bufferSize);
+
+ while (channel.read(buff) > 0) {
+ out.write(buff.array(), 0, buff.position());
+ buff.clear();
+ }
+ String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8);
+
+ assertEquals("Hello world", fileContent);
+ }
+ }
+
+ @Test
+ public void givenFile_whenReadAFileSectionIntoMemoryWithFileChannel_thenCorrect() throws IOException {
+
+ try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r");
+ FileChannel channel = reader.getChannel();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();) {
+
+ MappedByteBuffer buff = channel.map(FileChannel.MapMode.READ_ONLY, 6, 5);
+
+ if (buff.hasRemaining()) {
+ byte[] data = new byte[buff.remaining()];
+ buff.get(data);
+ assertEquals("world", new String(data, StandardCharsets.UTF_8));
+ }
+ }
+ }
+
+ @Test
+ public void whenWriteWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException {
+ String file = "src/test/resources/test_write_using_filechannel.txt";
+ try (RandomAccessFile writer = new RandomAccessFile(file, "rw");
+ FileChannel channel = writer.getChannel();) {
+ ByteBuffer buff = ByteBuffer.wrap("Hello world".getBytes(StandardCharsets.UTF_8));
+
+ channel.write(buff);
+
+ // now we verify whether the file was written correctly
+ RandomAccessFile reader = new RandomAccessFile(file, "r");
+ assertEquals("Hello world", reader.readLine());
+ reader.close();
+ }
+ }
+
+ @Test
+ public void givenFile_whenWriteAFileUsingLockAFileSectionWithFileChannel_thenCorrect() throws IOException {
+ try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "rw");
+ FileChannel channel = reader.getChannel();
+ FileLock fileLock = channel.tryLock(6, 5, Boolean.FALSE);) {
+
+ assertNotNull(fileLock);
+ }
+ }
+
+ @Test
+ public void givenFile_whenReadWithFileChannelGetPosition_thenCorrect() throws IOException {
+
+ try (ByteArrayOutputStream out = new ByteArrayOutputStream();
+ RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r");
+ FileChannel channel = reader.getChannel();) {
+
+ int bufferSize = 1024;
+ if (bufferSize > channel.size()) {
+ bufferSize = (int) channel.size();
+ }
+ ByteBuffer buff = ByteBuffer.allocate(bufferSize);
+
+ while (channel.read(buff) > 0) {
+ out.write(buff.array(), 0, buff.position());
+ buff.clear();
+ }
+
+ // the original file is 11 bytes long, so that's where the position pointer should be
+ assertEquals(11, channel.position());
+
+ channel.position(4);
+ assertEquals(4, channel.position());
+ }
+ }
+
+ @Test
+ public void whenGetFileSize_thenCorrect() throws IOException {
+
+ try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r");
+ FileChannel channel = reader.getChannel();) {
+
+ // the original file is 11 bytes long, so that's where the position pointer should be
+ assertEquals(11, channel.size());
+ }
+ }
+
+ @Test
+ public void whenTruncateFile_thenCorrect() throws IOException {
+ String input = "this is a test input";
+
+ FileOutputStream fout = new FileOutputStream("src/test/resources/test_truncate.txt");
+ FileChannel channel = fout.getChannel();
+
+ ByteBuffer buff = ByteBuffer.wrap(input.getBytes());
+ channel.write(buff);
+ buff.flip();
+
+ channel = channel.truncate(5);
+ assertEquals(5, channel.size());
+
+ fout.close();
+ channel.close();
+ }
+}
diff --git a/core-java-io/src/test/resources/test_truncate.txt b/core-java-io/src/test/resources/test_truncate.txt
new file mode 100644
index 0000000000..26d3b38cdd
--- /dev/null
+++ b/core-java-io/src/test/resources/test_truncate.txt
@@ -0,0 +1 @@
+this
\ No newline at end of file
diff --git a/core-java-io/src/test/resources/test_write_using_filechannel.txt b/core-java-io/src/test/resources/test_write_using_filechannel.txt
new file mode 100644
index 0000000000..70c379b63f
--- /dev/null
+++ b/core-java-io/src/test/resources/test_write_using_filechannel.txt
@@ -0,0 +1 @@
+Hello world
\ No newline at end of file
diff --git a/guava-collections-set/.gitignore b/guava-collections-set/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/guava-collections-set/.gitignore
@@ -0,0 +1,13 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file
diff --git a/guava-collections-set/pom.xml b/guava-collections-set/pom.xml
new file mode 100644
index 0000000000..46dcae492d
--- /dev/null
+++ b/guava-collections-set/pom.xml
@@ -0,0 +1,37 @@
+
+ 4.0.0
+ com.baeldung
+ guava-collections-set
+ 0.1.0-SNAPSHOT
+ guava-collections-set
+
+
+ com.baeldung
+ parent-java
+ 0.0.1-SNAPSHOT
+ ../parent-java
+
+
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+
+
+ guava-collections-set
+
+
+
+
+ 27.1-jre
+
+ 3.6.1
+
+
+
diff --git a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMultiSetUnitTest.java b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMultiSetUnitTest.java
new file mode 100644
index 0000000000..e74db29881
--- /dev/null
+++ b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMultiSetUnitTest.java
@@ -0,0 +1,92 @@
+package org.baeldung.guava;
+
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.Multiset;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class GuavaMultiSetUnitTest {
+
+ @Test
+ public void givenMultiSet_whenAddingValues_shouldReturnCorrectCount() {
+ Multiset bookStore = HashMultiset.create();
+ bookStore.add("Potter");
+ bookStore.add("Potter");
+ bookStore.add("Potter");
+
+ assertThat(bookStore.contains("Potter")).isTrue();
+ assertThat(bookStore.count("Potter")).isEqualTo(3);
+ }
+
+ @Test
+ public void givenMultiSet_whenRemovingValues_shouldReturnCorrectCount() {
+ Multiset bookStore = HashMultiset.create();
+ bookStore.add("Potter");
+ bookStore.add("Potter");
+
+ bookStore.remove("Potter");
+ assertThat(bookStore.contains("Potter")).isTrue();
+ assertThat(bookStore.count("Potter")).isEqualTo(1);
+ }
+
+ @Test
+ public void givenMultiSet_whenSetCount_shouldReturnCorrectCount() {
+ Multiset bookStore = HashMultiset.create();
+ bookStore.setCount("Potter", 50);
+ assertThat(bookStore.count("Potter")).isEqualTo(50);
+ }
+
+ @Test
+ public void givenMultiSet_whenSettingNegativeCount_shouldThrowException() {
+ Multiset bookStore = HashMultiset.create();
+ assertThatThrownBy(() -> bookStore.setCount("Potter", -1))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ public void givenMultiSet_whenSettingCountWithEmptySet_shouldBeSuccessful() {
+ Multiset bookStore = HashMultiset.create();
+ assertThat(bookStore.setCount("Potter", 0, 2)).isTrue();
+ }
+
+ @Test
+ public void givenMultiSet_whenSettingCountWithCorrectValue_shouldBeSuccessful() {
+ Multiset bookStore = HashMultiset.create();
+ bookStore.add("Potter");
+ bookStore.add("Potter");
+
+ assertThat(bookStore.setCount("Potter", 2, 52)).isTrue();
+ }
+
+ @Test
+ public void givenMultiSet_whenSettingCountWithIncorrectValue_shouldFail() {
+ Multiset bookStore = HashMultiset.create();
+ bookStore.add("Potter");
+ bookStore.add("Potter");
+
+ assertThat(bookStore.setCount("Potter", 5, 52)).isFalse();
+ }
+
+ @Test
+ public void givenMap_compareMultiSetOperations() {
+ Map bookStore = new HashMap<>();
+ bookStore.put("Potter", 3);
+
+ assertThat(bookStore.containsKey("Potter")).isTrue();
+ assertThat(bookStore.get("Potter")).isEqualTo(3);
+
+ bookStore.put("Potter", 2);
+ assertThat(bookStore.get("Potter")).isEqualTo(2);
+
+ bookStore.put("Potter", null);
+ assertThat(bookStore.containsKey("Potter")).isTrue();
+
+ bookStore.put("Potter", -1);
+ assertThat(bookStore.containsKey("Potter")).isTrue();
+ }
+}
\ No newline at end of file
diff --git a/jackson-simple/.gitignore b/jackson-simple/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/jackson-simple/.gitignore
@@ -0,0 +1,13 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file
diff --git a/jackson-simple/README.md b/jackson-simple/README.md
new file mode 100644
index 0000000000..be647e22d5
--- /dev/null
+++ b/jackson-simple/README.md
@@ -0,0 +1,13 @@
+=========
+### Jackson Articles that are also part of the e-book
+
+###The Course
+The "REST With Spring" Classes: http://bit.ly/restwithspring
+
+### Relevant Articles:
+- [Jackson Ignore Properties on Marshalling](http://www.baeldung.com/jackson-ignore-properties-on-serialization)
+- [Jackson Unmarshalling json with Unknown Properties](http://www.baeldung.com/jackson-deserialize-json-unknown-properties)
+- [Jackson Annotation Examples](http://www.baeldung.com/jackson-annotations)
+- [Intro to the Jackson ObjectMapper](http://www.baeldung.com/jackson-object-mapper-tutorial)
+- [Ignore Null Fields with Jackson](http://www.baeldung.com/jackson-ignore-null-fields)
+- [Jackson – Change Name of Field](http://www.baeldung.com/jackson-name-of-property)
diff --git a/jackson-simple/pom.xml b/jackson-simple/pom.xml
new file mode 100644
index 0000000000..5023ad87b6
--- /dev/null
+++ b/jackson-simple/pom.xml
@@ -0,0 +1,131 @@
+
+ 4.0.0
+ jackson-simple
+ 0.1-SNAPSHOT
+ jackson-simple
+
+
+ com.baeldung
+ parent-java
+ 0.0.1-SNAPSHOT
+ ../parent-java
+
+
+
+
+
+ commons-io
+ commons-io
+ ${commons-io.version}
+
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-xml
+ ${jackson.version}
+
+
+
+ org.apache.commons
+ commons-collections4
+ ${commons-collections4.version}
+
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ ${jackson.version}
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-joda
+ ${jackson.version}
+
+
+
+ com.fasterxml.jackson.module
+ jackson-module-jsonSchema
+ ${jackson.version}
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jdk8
+ ${jackson.version}
+
+
+
+ joda-time
+ joda-time
+ ${joda-time.version}
+
+
+
+ com.google.code.gson
+ gson
+ ${gson.version}
+
+
+
+
+
+ io.rest-assured
+ json-schema-validator
+ ${rest-assured.version}
+ test
+
+
+
+ io.rest-assured
+ json-path
+ ${rest-assured.version}
+ test
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+
+
+ jackson-simple
+
+
+ src/main/resources
+ true
+
+
+
+
+
+
+ 3.8
+ 2.10
+ 2.8.5
+ 4.2
+
+
+ 3.1.1
+ 3.11.0
+
+
+
diff --git a/jackson-simple/src/main/resources/logback.xml b/jackson-simple/src/main/resources/logback.xml
new file mode 100644
index 0000000000..56af2d397e
--- /dev/null
+++ b/jackson-simple/src/main/resources/logback.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/AliasBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/AliasBean.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/AliasBean.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/AliasBean.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithCreator.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithCreator.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithCreator.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithCreator.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithCustomAnnotation.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithCustomAnnotation.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithCustomAnnotation.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithCustomAnnotation.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithFilter.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithFilter.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithFilter.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithFilter.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithGetter.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithGetter.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithGetter.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithGetter.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithIgnore.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithIgnore.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithIgnore.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithIgnore.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithInject.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithInject.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithInject.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithInject.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/ExtendableBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/ExtendableBean.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/ExtendableBean.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/ExtendableBean.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/MyBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/MyBean.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/MyBean.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/MyBean.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/PrivateBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/PrivateBean.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/PrivateBean.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/PrivateBean.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/RawBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/RawBean.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/RawBean.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/RawBean.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/UnwrappedUser.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/UnwrappedUser.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/UnwrappedUser.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/UnwrappedUser.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/UserWithIgnoreType.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/UserWithIgnoreType.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/UserWithIgnoreType.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/UserWithIgnoreType.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/Zoo.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/Zoo.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/annotation/Zoo.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/Zoo.java
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIdentity.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIdentity.java
new file mode 100644
index 0000000000..25de4a8f7a
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIdentity.java
@@ -0,0 +1,21 @@
+package com.baeldung.jackson.bidirection;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
+@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
+public class ItemWithIdentity {
+ public int id;
+ public String itemName;
+ public UserWithIdentity owner;
+
+ public ItemWithIdentity() {
+ super();
+ }
+
+ public ItemWithIdentity(final int id, final String itemName, final UserWithIdentity owner) {
+ this.id = id;
+ this.itemName = itemName;
+ this.owner = owner;
+ }
+}
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIgnore.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIgnore.java
new file mode 100644
index 0000000000..910ccec174
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIgnore.java
@@ -0,0 +1,17 @@
+package com.baeldung.jackson.bidirection;
+
+public class ItemWithIgnore {
+ public int id;
+ public String itemName;
+ public UserWithIgnore owner;
+
+ public ItemWithIgnore() {
+ super();
+ }
+
+ public ItemWithIgnore(final int id, final String itemName, final UserWithIgnore owner) {
+ this.id = id;
+ this.itemName = itemName;
+ this.owner = owner;
+ }
+}
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithRef.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithRef.java
new file mode 100644
index 0000000000..0ca8d721e8
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithRef.java
@@ -0,0 +1,21 @@
+package com.baeldung.jackson.bidirection;
+
+import com.fasterxml.jackson.annotation.JsonManagedReference;
+
+public class ItemWithRef {
+ public int id;
+ public String itemName;
+
+ @JsonManagedReference
+ public UserWithRef owner;
+
+ public ItemWithRef() {
+ super();
+ }
+
+ public ItemWithRef(final int id, final String itemName, final UserWithRef owner) {
+ this.id = id;
+ this.itemName = itemName;
+ this.owner = owner;
+ }
+}
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIdentity.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIdentity.java
new file mode 100644
index 0000000000..db83a09389
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIdentity.java
@@ -0,0 +1,28 @@
+package com.baeldung.jackson.bidirection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
+@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
+public class UserWithIdentity {
+ public int id;
+ public String name;
+ public List userItems;
+
+ public UserWithIdentity() {
+ super();
+ }
+
+ public UserWithIdentity(final int id, final String name) {
+ this.id = id;
+ this.name = name;
+ userItems = new ArrayList();
+ }
+
+ public void addItem(final ItemWithIdentity item) {
+ userItems.add(item);
+ }
+}
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIgnore.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIgnore.java
new file mode 100644
index 0000000000..857a373cc5
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIgnore.java
@@ -0,0 +1,28 @@
+package com.baeldung.jackson.bidirection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+public class UserWithIgnore {
+ public int id;
+ public String name;
+
+ @JsonIgnore
+ public List userItems;
+
+ public UserWithIgnore() {
+ super();
+ }
+
+ public UserWithIgnore(final int id, final String name) {
+ this.id = id;
+ this.name = name;
+ userItems = new ArrayList();
+ }
+
+ public void addItem(final ItemWithIgnore item) {
+ userItems.add(item);
+ }
+}
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithRef.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithRef.java
new file mode 100644
index 0000000000..3de03fc651
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithRef.java
@@ -0,0 +1,28 @@
+package com.baeldung.jackson.bidirection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonBackReference;
+
+public class UserWithRef {
+ public int id;
+ public String name;
+
+ @JsonBackReference
+ public List userItems;
+
+ public UserWithRef() {
+ super();
+ }
+
+ public UserWithRef(final int id, final String name) {
+ this.id = id;
+ this.name = name;
+ userItems = new ArrayList();
+ }
+
+ public void addItem(final ItemWithRef item) {
+ userItems.add(item);
+ }
+}
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java
new file mode 100644
index 0000000000..90c7d9fbac
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java
@@ -0,0 +1,36 @@
+package com.baeldung.jackson.date;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+public class CustomDateDeserializer extends StdDeserializer {
+
+ private static final long serialVersionUID = -5451717385630622729L;
+ private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+
+ public CustomDateDeserializer() {
+ this(null);
+ }
+
+ public CustomDateDeserializer(final Class> vc) {
+ super(vc);
+ }
+
+ @Override
+ public Date deserialize(final JsonParser jsonparser, final DeserializationContext context) throws IOException, JsonProcessingException {
+ final String date = jsonparser.getText();
+ try {
+ return formatter.parse(date);
+ } catch (final ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java
new file mode 100644
index 0000000000..d840e1940f
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java
@@ -0,0 +1,29 @@
+package com.baeldung.jackson.date;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+public class CustomDateSerializer extends StdSerializer {
+
+ private static final long serialVersionUID = -2894356342227378312L;
+ private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+
+ public CustomDateSerializer() {
+ this(null);
+ }
+
+ public CustomDateSerializer(final Class t) {
+ super(t);
+ }
+
+ @Override
+ public void serialize(final Date value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException {
+ gen.writeString(formatter.format(value));
+ }
+}
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithFormat.java b/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithFormat.java
new file mode 100644
index 0000000000..607e694cef
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithFormat.java
@@ -0,0 +1,29 @@
+package com.baeldung.jackson.date;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+public class EventWithFormat {
+ public String name;
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
+ public Date eventDate;
+
+ public EventWithFormat() {
+ super();
+ }
+
+ public EventWithFormat(final String name, final Date eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public Date getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithSerializer.java
new file mode 100644
index 0000000000..c359b5c846
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithSerializer.java
@@ -0,0 +1,31 @@
+package com.baeldung.jackson.date;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+public class EventWithSerializer {
+ public String name;
+
+ @JsonDeserialize(using = CustomDateDeserializer.class)
+ @JsonSerialize(using = CustomDateSerializer.class)
+ public Date eventDate;
+
+ public EventWithSerializer() {
+ super();
+ }
+
+ public EventWithSerializer(final String name, final Date eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public Date getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java b/jackson-simple/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java
new file mode 100644
index 0000000000..eaba9a7173
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java
@@ -0,0 +1,41 @@
+package com.baeldung.jackson.deserialization;
+
+import java.io.IOException;
+
+import com.baeldung.jackson.dtos.ItemWithSerializer;
+import com.baeldung.jackson.dtos.User;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+import com.fasterxml.jackson.databind.node.IntNode;
+
+public class ItemDeserializerOnClass extends StdDeserializer {
+
+ private static final long serialVersionUID = 5579141241817332594L;
+
+ public ItemDeserializerOnClass() {
+ this(null);
+ }
+
+ public ItemDeserializerOnClass(final Class> vc) {
+ super(vc);
+ }
+
+ /**
+ * {"id":1,"itemNr":"theItem","owner":2}
+ */
+ @Override
+ public ItemWithSerializer deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
+ final JsonNode node = jp.getCodec()
+ .readTree(jp);
+ final int id = (Integer) ((IntNode) node.get("id")).numberValue();
+ final String itemName = node.get("itemName")
+ .asText();
+ final int userId = (Integer) ((IntNode) node.get("owner")).numberValue();
+
+ return new ItemWithSerializer(id, itemName, new User(userId, null));
+ }
+
+}
\ No newline at end of file
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/Item.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/Item.java
new file mode 100644
index 0000000000..6fce2bc88e
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/Item.java
@@ -0,0 +1,32 @@
+package com.baeldung.jackson.dtos;
+
+public class Item {
+ public int id;
+ public String itemName;
+ public User owner;
+
+ public Item() {
+ super();
+ }
+
+ public Item(final int id, final String itemName, final User owner) {
+ this.id = id;
+ this.itemName = itemName;
+ this.owner = owner;
+ }
+
+ // API
+
+ public int getId() {
+ return id;
+ }
+
+ public String getItemName() {
+ return itemName;
+ }
+
+ public User getOwner() {
+ return owner;
+ }
+
+}
\ No newline at end of file
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ItemWithSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ItemWithSerializer.java
new file mode 100644
index 0000000000..aea9aa770d
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ItemWithSerializer.java
@@ -0,0 +1,36 @@
+package com.baeldung.jackson.dtos;
+
+import com.baeldung.jackson.deserialization.ItemDeserializerOnClass;
+import com.baeldung.jackson.serialization.ItemSerializerOnClass;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+@JsonSerialize(using = ItemSerializerOnClass.class)
+@JsonDeserialize(using = ItemDeserializerOnClass.class)
+public class ItemWithSerializer {
+ public final int id;
+ public final String itemName;
+ public final User owner;
+
+ public ItemWithSerializer(final int id, final String itemName, final User owner) {
+ this.id = id;
+ this.itemName = itemName;
+ this.owner = owner;
+ }
+
+ // API
+
+ public int getId() {
+ return id;
+ }
+
+ public String getItemName() {
+ return itemName;
+ }
+
+ public User getOwner() {
+ return owner;
+ }
+
+}
\ No newline at end of file
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDto.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDto.java
new file mode 100644
index 0000000000..49cf07baea
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDto.java
@@ -0,0 +1,54 @@
+package com.baeldung.jackson.dtos;
+
+public class MyDto {
+
+ private String stringValue;
+ private int intValue;
+ private boolean booleanValue;
+
+ public MyDto() {
+ super();
+ }
+
+ public MyDto(final String stringValue, final int intValue, final boolean booleanValue) {
+ super();
+
+ this.stringValue = stringValue;
+ this.intValue = intValue;
+ this.booleanValue = booleanValue;
+ }
+
+ // API
+
+ public String getStringValue() {
+ return stringValue;
+ }
+
+ public void setStringValue(final String stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+
+ public void setIntValue(final int intValue) {
+ this.intValue = intValue;
+ }
+
+ public boolean isBooleanValue() {
+ return booleanValue;
+ }
+
+ public void setBooleanValue(final boolean booleanValue) {
+ this.booleanValue = booleanValue;
+ }
+
+ //
+
+ @Override
+ public String toString() {
+ return "MyDto [stringValue=" + stringValue + ", intValue=" + intValue + ", booleanValue=" + booleanValue + "]";
+ }
+
+}
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoFieldNameChanged.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoFieldNameChanged.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoFieldNameChanged.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoFieldNameChanged.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoIncludeNonDefault.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoIncludeNonDefault.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoIncludeNonDefault.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoIncludeNonDefault.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessors.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessors.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessors.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessors.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessorsAndFieldVisibility.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessorsAndFieldVisibility.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessorsAndFieldVisibility.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessorsAndFieldVisibility.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithFilter.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoWithFilter.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithFilter.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoWithFilter.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/User.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/User.java
new file mode 100644
index 0000000000..2418e8070d
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/User.java
@@ -0,0 +1,26 @@
+package com.baeldung.jackson.dtos;
+
+public class User {
+ public int id;
+ public String name;
+
+ public User() {
+ super();
+ }
+
+ public User(final int id, final String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ // API
+
+ public int getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreField.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreField.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreField.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreField.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreFieldByName.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreFieldByName.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreFieldByName.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreFieldByName.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreNull.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreNull.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreNull.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreNull.java
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java
new file mode 100644
index 0000000000..69c476d8a5
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java
@@ -0,0 +1,29 @@
+package com.baeldung.jackson.dtos.withEnum;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+public enum DistanceEnumWithValue {
+ KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001);
+
+ private String unit;
+ private final double meters;
+
+ private DistanceEnumWithValue(String unit, double meters) {
+ this.unit = unit;
+ this.meters = meters;
+ }
+
+ @JsonValue
+ public double getMeters() {
+ return meters;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public void setUnit(String unit) {
+ this.unit = unit;
+ }
+
+}
\ No newline at end of file
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRoot.java b/jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRoot.java
new file mode 100644
index 0000000000..d879c16e6a
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRoot.java
@@ -0,0 +1,18 @@
+package com.baeldung.jackson.exception;
+
+import com.fasterxml.jackson.annotation.JsonRootName;
+
+@JsonRootName(value = "user")
+public class UserWithRoot {
+ public int id;
+ public String name;
+
+ public UserWithRoot() {
+ super();
+ }
+
+ public UserWithRoot(final int id, final String name) {
+ this.id = id;
+ this.name = name;
+ }
+}
diff --git a/jackson/src/test/java/com/baeldung/jackson/exception/UserWithRootNamespace.java b/jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRootNamespace.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/exception/UserWithRootNamespace.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRootNamespace.java
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Item.java b/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Item.java
new file mode 100644
index 0000000000..26d20d4847
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Item.java
@@ -0,0 +1,36 @@
+package com.baeldung.jackson.jsonview;
+
+import com.fasterxml.jackson.annotation.JsonView;
+
+public class Item {
+ @JsonView(Views.Public.class)
+ public int id;
+
+ @JsonView(Views.Public.class)
+ public String itemName;
+
+ @JsonView(Views.Internal.class)
+ public String ownerName;
+
+ public Item() {
+ super();
+ }
+
+ public Item(final int id, final String itemName, final String ownerName) {
+ this.id = id;
+ this.itemName = itemName;
+ this.ownerName = ownerName;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public String getItemName() {
+ return itemName;
+ }
+
+ public String getOwnerName() {
+ return ownerName;
+ }
+}
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Views.java b/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Views.java
new file mode 100644
index 0000000000..65950b7f9f
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Views.java
@@ -0,0 +1,9 @@
+package com.baeldung.jackson.jsonview;
+
+public class Views {
+ public static class Public {
+ }
+
+ public static class Internal extends Public {
+ }
+}
diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/JavaReadWriteJsonExampleUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/JavaReadWriteJsonExampleUnitTest.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/JavaReadWriteJsonExampleUnitTest.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/JavaReadWriteJsonExampleUnitTest.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/SerializationDeserializationFeatureUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/SerializationDeserializationFeatureUnitTest.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/SerializationDeserializationFeatureUnitTest.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/SerializationDeserializationFeatureUnitTest.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java
diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java b/jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java
new file mode 100644
index 0000000000..1fdf44e17c
--- /dev/null
+++ b/jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java
@@ -0,0 +1,32 @@
+package com.baeldung.jackson.serialization;
+
+import java.io.IOException;
+
+import com.baeldung.jackson.dtos.ItemWithSerializer;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+public class ItemSerializerOnClass extends StdSerializer {
+
+ private static final long serialVersionUID = -1760959597313610409L;
+
+ public ItemSerializerOnClass() {
+ this(null);
+ }
+
+ public ItemSerializerOnClass(final Class t) {
+ super(t);
+ }
+
+ @Override
+ public final void serialize(final ItemWithSerializer value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException {
+ jgen.writeStartObject();
+ jgen.writeNumberField("id", value.id);
+ jgen.writeStringField("itemName", value.itemName);
+ jgen.writeNumberField("owner", value.owner.id);
+ jgen.writeEndObject();
+ }
+
+}
\ No newline at end of file
diff --git a/jackson/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonAnnotationUnitTest.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationUnitTest.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonAnnotationUnitTest.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java
diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonSerializationUnitTest.java
similarity index 100%
rename from jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationUnitTest.java
rename to jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonSerializationUnitTest.java
diff --git a/jackson-simple/src/test/resources/.gitignore b/jackson-simple/src/test/resources/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/jackson-simple/src/test/resources/.gitignore
@@ -0,0 +1,13 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file
diff --git a/jackson/README.md b/jackson/README.md
index eeb8f1b874..794ddc04d9 100644
--- a/jackson/README.md
+++ b/jackson/README.md
@@ -6,9 +6,7 @@
The "REST With Spring" Classes: http://bit.ly/restwithspring
### Relevant Articles:
-- [Jackson Ignore Properties on Marshalling](http://www.baeldung.com/jackson-ignore-properties-on-serialization)
- [Jackson – Unmarshall to Collection/Array](http://www.baeldung.com/jackson-collection-array)
-- [Jackson Unmarshalling json with Unknown Properties](http://www.baeldung.com/jackson-deserialize-json-unknown-properties)
- [Jackson – Custom Serializer](http://www.baeldung.com/jackson-custom-serialization)
- [Getting Started with Custom Deserialization in Jackson](http://www.baeldung.com/jackson-deserialization)
- [Jackson Exceptions – Problems and Solutions](http://www.baeldung.com/jackson-exception)
@@ -17,10 +15,8 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Jackson JSON Tutorial](http://www.baeldung.com/jackson)
- [Jackson – Working with Maps and nulls](http://www.baeldung.com/jackson-map-null-values-or-null-key)
- [Jackson – Decide What Fields Get Serialized/Deserialized](http://www.baeldung.com/jackson-field-serializable-deserializable-or-not)
-- [Jackson Annotation Examples](http://www.baeldung.com/jackson-annotations)
- [Working with Tree Model Nodes in Jackson](http://www.baeldung.com/jackson-json-node-tree-model)
- [Jackson vs Gson](http://www.baeldung.com/jackson-vs-gson)
-- [Intro to the Jackson ObjectMapper](http://www.baeldung.com/jackson-object-mapper-tutorial)
- [XML Serialization and Deserialization with Jackson](http://www.baeldung.com/jackson-xml-serialization-and-deserialization)
- [More Jackson Annotations](http://www.baeldung.com/jackson-advanced-annotations)
- [Inheritance with Jackson](http://www.baeldung.com/jackson-inheritance)
@@ -31,9 +27,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Jackson – JsonMappingException (No serializer found for class)](http://www.baeldung.com/jackson-jsonmappingexception)
- [How To Serialize Enums as JSON Objects with Jackson](http://www.baeldung.com/jackson-serialize-enums)
- [Jackson – Marshall String to JsonNode](http://www.baeldung.com/jackson-json-to-jsonnode)
-- [Ignore Null Fields with Jackson](http://www.baeldung.com/jackson-ignore-null-fields)
- [Jackson – Unmarshall to Collection/Array](http://www.baeldung.com/jackson-collection-array)
-- [Jackson – Change Name of Field](http://www.baeldung.com/jackson-name-of-property)
- [Serialize Only Fields that meet a Custom Criteria with Jackson](http://www.baeldung.com/jackson-serialize-field-custom-criteria)
- [Mapping Nested Values with Jackson](http://www.baeldung.com/jackson-nested-values)
- [Convert XML to JSON Using Jackson](https://www.baeldung.com/jackson-convert-xml-json)
diff --git a/jackson/src/test/java/com/baeldung/jackson/test/UnitTestSuite.java b/jackson/src/test/java/com/baeldung/jackson/test/UnitTestSuite.java
index 6be2f29baa..e783c67f5b 100644
--- a/jackson/src/test/java/com/baeldung/jackson/test/UnitTestSuite.java
+++ b/jackson/src/test/java/com/baeldung/jackson/test/UnitTestSuite.java
@@ -12,8 +12,6 @@ import org.junit.runners.Suite;
,JacksonDeserializationUnitTest.class
,JacksonDeserializationUnitTest.class
,JacksonPrettyPrintUnitTest.class
- ,JacksonSerializationIgnoreUnitTest.class
- ,JacksonSerializationUnitTest.class
,SandboxUnitTest.class
,JacksonFieldUnitTest.class
}) // @formatter:on
diff --git a/persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/resources/data.sql b/persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/resources/data.sql
new file mode 100644
index 0000000000..2d7b446005
--- /dev/null
+++ b/persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/resources/data.sql
@@ -0,0 +1,13 @@
+DROP TABLE IF EXISTS billionaires;
+
+CREATE TABLE billionaires (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ first_name VARCHAR(250) NOT NULL,
+ last_name VARCHAR(250) NOT NULL,
+ career VARCHAR(250) DEFAULT NULL
+);
+
+INSERT INTO billionaires (first_name, last_name, career) VALUES
+('Aliko', 'Dangote', 'Billionaire Industrialist'),
+('Bill', 'Gates', 'Billionaire Tech Entrepreneur'),
+('Folrunsho', 'Alakija', 'Billionaire Oil Magnate');
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ff2fa55410..b102b5cd30 100644
--- a/pom.xml
+++ b/pom.xml
@@ -381,7 +381,7 @@
core-java-8
core-java-8-2
- core-java-lambdas
+ core-java-lambdas
core-java-arrays
@@ -443,6 +443,7 @@
jackson
jackson-2
+ jackson-simple
java-collections-conversions
java-collections-maps
java-collections-maps-2
@@ -541,6 +542,7 @@
tensorflow-java
spring-boot-flowable
+ spring-security-kerberos
@@ -768,6 +770,7 @@
tensorflow-java
spring-boot-flowable
+ spring-security-kerberos
@@ -912,6 +915,7 @@
persistence-modules/spring-hibernate-5
spring-boot-flowable
+ spring-security-kerberos
@@ -1103,6 +1107,7 @@
jackson
jackson-2
+ jackson-simple
java-collections-conversions
java-collections-maps
java-collections-maps-2
diff --git a/spring-boot-testing/src/main/java/com/baeldung/component/OtherComponent.java b/spring-boot-testing/src/main/java/com/baeldung/component/OtherComponent.java
new file mode 100644
index 0000000000..97f001a9e5
--- /dev/null
+++ b/spring-boot-testing/src/main/java/com/baeldung/component/OtherComponent.java
@@ -0,0 +1,19 @@
+package com.baeldung.component;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class OtherComponent {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OtherComponent.class);
+
+ public void processData() {
+ LOG.trace("This is a TRACE log from another package");
+ LOG.debug("This is a DEBUG log from another package");
+ LOG.info("This is an INFO log from another package");
+ LOG.error("This is an ERROR log from another package");
+ }
+
+}
diff --git a/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelApplication.java b/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelApplication.java
new file mode 100644
index 0000000000..ed8218c6a3
--- /dev/null
+++ b/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelApplication.java
@@ -0,0 +1,15 @@
+package com.baeldung.testloglevel;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import com.baeldung.boot.Application;
+
+@SpringBootApplication(scanBasePackages = {"com.baeldung.testloglevel", "com.baeldung.component"})
+public class TestLogLevelApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelController.java b/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelController.java
new file mode 100644
index 0000000000..22078562b4
--- /dev/null
+++ b/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelController.java
@@ -0,0 +1,31 @@
+package com.baeldung.testloglevel;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.component.OtherComponent;
+
+@RestController
+public class TestLogLevelController {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TestLogLevelController.class);
+
+ @Autowired
+ private OtherComponent otherComponent;
+
+ @GetMapping("/testLogLevel")
+ public String testLogLevel() {
+ LOG.trace("This is a TRACE log");
+ LOG.debug("This is a DEBUG log");
+ LOG.info("This is an INFO log");
+ LOG.error("This is an ERROR log");
+
+ otherComponent.processData();
+
+ return "Added some log output to console...";
+ }
+
+}
diff --git a/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackMultiProfileTestLogLevelIntegrationTest.java b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackMultiProfileTestLogLevelIntegrationTest.java
new file mode 100644
index 0000000000..7a1eb4adbe
--- /dev/null
+++ b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackMultiProfileTestLogLevelIntegrationTest.java
@@ -0,0 +1,70 @@
+package com.baeldung.testloglevel;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.rule.OutputCapture;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = TestLogLevelApplication.class)
+@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
+@ActiveProfiles("logback-test2")
+public class LogbackMultiProfileTestLogLevelIntegrationTest {
+
+ @Autowired
+ private TestRestTemplate restTemplate;
+
+ @Rule
+ public OutputCapture outputCapture = new OutputCapture();
+
+ private String baseUrl = "/testLogLevel";
+
+ @Test
+ public void givenErrorRootLevelAndTraceLevelForOurPackage_whenCall_thenPrintTraceLogsForOurPackage() {
+ ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class);
+
+ assertThat(response.getStatusCode().value()).isEqualTo(200);
+ assertThatOutputContainsLogForOurPackage("TRACE");
+ }
+
+ @Test
+ public void givenErrorRootLevelAndTraceLevelForOurPackage_whenCall_thenNoTraceLogsForOtherPackages() {
+ ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class);
+
+ assertThat(response.getStatusCode().value()).isEqualTo(200);
+ assertThatOutputDoesntContainLogForOtherPackages("TRACE");
+ }
+
+ @Test
+ public void givenErrorRootLevelAndTraceLevelForOurPackage_whenCall_thenPrintErrorLogs() {
+ ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class);
+
+ assertThat(response.getStatusCode().value()).isEqualTo(200);
+ assertThatOutputContainsLogForOurPackage("ERROR");
+ assertThatOutputContainsLogForOtherPackages("ERROR");
+ }
+
+ private void assertThatOutputContainsLogForOurPackage(String level) {
+ assertThat(outputCapture.toString()).containsPattern("TestLogLevelController.*" + level + ".*");
+ }
+
+ private void assertThatOutputDoesntContainLogForOtherPackages(String level) {
+ assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).doesNotContain(level);
+ }
+
+ private void assertThatOutputContainsLogForOtherPackages(String level) {
+ assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).contains(level);
+ }
+
+}
diff --git a/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackTestLogLevelIntegrationTest.java b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackTestLogLevelIntegrationTest.java
new file mode 100644
index 0000000000..af3bafdc2e
--- /dev/null
+++ b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackTestLogLevelIntegrationTest.java
@@ -0,0 +1,70 @@
+package com.baeldung.testloglevel;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.rule.OutputCapture;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = TestLogLevelApplication.class)
+@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
+@ActiveProfiles("logback-test")
+public class LogbackTestLogLevelIntegrationTest {
+
+ @Autowired
+ private TestRestTemplate restTemplate;
+
+ @Rule
+ public OutputCapture outputCapture = new OutputCapture();
+
+ private String baseUrl = "/testLogLevel";
+
+ @Test
+ public void givenErrorRootLevelAndDebugLevelForOurPackage_whenCall_thenPrintDebugLogsForOurPackage() {
+ ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class);
+
+ assertThat(response.getStatusCode().value()).isEqualTo(200);
+ assertThatOutputContainsLogForOurPackage("DEBUG");
+ }
+
+ @Test
+ public void givenErrorRootLevelAndDebugLevelForOurPackage_whenCall_thenNoDebugLogsForOtherPackages() {
+ ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class);
+
+ assertThat(response.getStatusCode().value()).isEqualTo(200);
+ assertThatOutputDoesntContainLogForOtherPackages("DEBUG");
+ }
+
+ @Test
+ public void givenErrorRootLevelAndDebugLevelForOurPackage_whenCall_thenPrintErrorLogs() {
+ ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class);
+
+ assertThat(response.getStatusCode().value()).isEqualTo(200);
+ assertThatOutputContainsLogForOurPackage("ERROR");
+ assertThatOutputContainsLogForOtherPackages("ERROR");
+ }
+
+ private void assertThatOutputContainsLogForOurPackage(String level) {
+ assertThat(outputCapture.toString()).containsPattern("TestLogLevelController.*" + level + ".*");
+ }
+
+ private void assertThatOutputDoesntContainLogForOtherPackages(String level) {
+ assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).doesNotContain(level);
+ }
+
+ private void assertThatOutputContainsLogForOtherPackages(String level) {
+ assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).contains(level);
+ }
+
+}
diff --git a/spring-boot-testing/src/test/java/com/baeldung/testloglevel/TestLogLevelWithProfileIntegrationTest.java b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/TestLogLevelWithProfileIntegrationTest.java
new file mode 100644
index 0000000000..5609ce6c01
--- /dev/null
+++ b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/TestLogLevelWithProfileIntegrationTest.java
@@ -0,0 +1,70 @@
+package com.baeldung.testloglevel;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.rule.OutputCapture;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = TestLogLevelApplication.class)
+@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
+@ActiveProfiles("logging-test")
+public class TestLogLevelWithProfileIntegrationTest {
+
+ @Autowired
+ private TestRestTemplate restTemplate;
+
+ @Rule
+ public OutputCapture outputCapture = new OutputCapture();
+
+ private String baseUrl = "/testLogLevel";
+
+ @Test
+ public void givenInfoRootLevelAndDebugLevelForOurPackage_whenCall_thenPrintDebugLogsForOurPackage() {
+ ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class);
+
+ assertThat(response.getStatusCode().value()).isEqualTo(200);
+ assertThatOutputContainsLogForOurPackage("DEBUG");
+ }
+
+ @Test
+ public void givenInfoRootLevelAndDebugLevelForOurPackage_whenCall_thenNoDebugLogsForOtherPackages() {
+ ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class);
+
+ assertThat(response.getStatusCode().value()).isEqualTo(200);
+ assertThatOutputDoesntContainLogForOtherPackages("DEBUG");
+ }
+
+ @Test
+ public void givenInfoRootLevelAndDebugLevelForOurPackage_whenCall_thenPrintInfoLogs() {
+ ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class);
+
+ assertThat(response.getStatusCode().value()).isEqualTo(200);
+ assertThatOutputContainsLogForOurPackage("INFO");
+ assertThatOutputContainsLogForOtherPackages("INFO");
+ }
+
+ private void assertThatOutputContainsLogForOurPackage(String level) {
+ assertThat(outputCapture.toString()).containsPattern("TestLogLevelController.*" + level + ".*");
+ }
+
+ private void assertThatOutputDoesntContainLogForOtherPackages(String level) {
+ assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).doesNotContain(level);
+ }
+
+ private void assertThatOutputContainsLogForOtherPackages(String level) {
+ assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).contains(level);
+ }
+
+}
diff --git a/spring-boot-testing/src/test/resources/application-logback-test.properties b/spring-boot-testing/src/test/resources/application-logback-test.properties
new file mode 100644
index 0000000000..587302fa01
--- /dev/null
+++ b/spring-boot-testing/src/test/resources/application-logback-test.properties
@@ -0,0 +1 @@
+logging.config=classpath:logback-test.xml
diff --git a/spring-boot-testing/src/test/resources/application-logback-test2.properties b/spring-boot-testing/src/test/resources/application-logback-test2.properties
new file mode 100644
index 0000000000..aeed46e3ca
--- /dev/null
+++ b/spring-boot-testing/src/test/resources/application-logback-test2.properties
@@ -0,0 +1 @@
+logging.config=classpath:logback-multiprofile.xml
\ No newline at end of file
diff --git a/spring-boot-testing/src/test/resources/application-logging-test.properties b/spring-boot-testing/src/test/resources/application-logging-test.properties
new file mode 100644
index 0000000000..b5adb4cc11
--- /dev/null
+++ b/spring-boot-testing/src/test/resources/application-logging-test.properties
@@ -0,0 +1,2 @@
+logging.level.com.baeldung.testloglevel=DEBUG
+logging.level.root=INFO
\ No newline at end of file
diff --git a/spring-boot-testing/src/test/resources/logback-multiprofile.xml b/spring-boot-testing/src/test/resources/logback-multiprofile.xml
new file mode 100644
index 0000000000..be790234f2
--- /dev/null
+++ b/spring-boot-testing/src/test/resources/logback-multiprofile.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-boot-testing/src/test/resources/logback-test.xml b/spring-boot-testing/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..0528aa88f3
--- /dev/null
+++ b/spring-boot-testing/src/test/resources/logback-test.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
diff --git a/spring-core/pom.xml b/spring-core/pom.xml
index d348d742e7..814addecdd 100644
--- a/spring-core/pom.xml
+++ b/spring-core/pom.xml
@@ -10,9 +10,9 @@
com.baeldung
- parent-spring-4
+ parent-spring-5
0.0.1-SNAPSHOT
- ../parent-spring-4
+ ../parent-spring-5
diff --git a/spring-security-kerberos/README.md b/spring-security-kerberos/README.md
new file mode 100644
index 0000000000..0338c2058c
--- /dev/null
+++ b/spring-security-kerberos/README.md
@@ -0,0 +1,10 @@
+## @PreFilter and @PostFilter annotations
+
+### Build the Project ###
+
+```
+mvn clean install
+```
+
+### Relevant Articles:
+- [Spring Security – Kerberos](http://www.baeldung.com/xxxxxx)
diff --git a/spring-security-kerberos/pom.xml b/spring-security-kerberos/pom.xml
new file mode 100644
index 0000000000..35c4ba4926
--- /dev/null
+++ b/spring-security-kerberos/pom.xml
@@ -0,0 +1,61 @@
+
+ 4.0.0
+ com.baeldung
+ spring-security-kerberos
+ 0.1-SNAPSHOT
+ spring-security-kerberos
+ war
+
+ parent-boot-1
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../parent-boot-1
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ org.springframework.security.kerberos
+ spring-security-kerberos-core
+ 1.0.1.RELEASE
+
+
+ org.springframework.security.kerberos
+ spring-security-kerberos-web
+ 1.0.1.RELEASE
+
+
+ org.springframework.security.kerberos
+ spring-security-kerberos-client
+ 1.0.1.RELEASE
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+
+
+
diff --git a/spring-security-kerberos/src/main/java/org/baeldung/Application.java b/spring-security-kerberos/src/main/java/org/baeldung/Application.java
new file mode 100644
index 0000000000..39c2b51356
--- /dev/null
+++ b/spring-security-kerberos/src/main/java/org/baeldung/Application.java
@@ -0,0 +1,13 @@
+package org.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/spring-security-kerberos/src/main/java/org/baeldung/config/WebSecurityConfig.java b/spring-security-kerberos/src/main/java/org/baeldung/config/WebSecurityConfig.java
new file mode 100644
index 0000000000..49a1cf0a8e
--- /dev/null
+++ b/spring-security-kerberos/src/main/java/org/baeldung/config/WebSecurityConfig.java
@@ -0,0 +1,87 @@
+package org.baeldung.config;
+
+import org.baeldung.security.DummyUserDetailsService;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider;
+import org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider;
+import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient;
+import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator;
+import org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter;
+import org.springframework.security.kerberos.web.authentication.SpnegoEntryPoint;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
+
+@Configuration
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.authorizeRequests()
+ .anyRequest()
+ .authenticated()
+ .and()
+ .addFilterBefore(spnegoAuthenticationProcessingFilter(authenticationManagerBean()), BasicAuthenticationFilter.class);
+ }
+
+ @Override
+ @Bean
+ public AuthenticationManager authenticationManagerBean() throws Exception {
+ return super.authenticationManagerBean();
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.authenticationProvider(kerberosAuthenticationProvider())
+ .authenticationProvider(kerberosServiceAuthenticationProvider());
+ }
+
+ @Bean
+ public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
+ KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider();
+ SunJaasKerberosClient client = new SunJaasKerberosClient();
+ client.setDebug(true);
+ provider.setKerberosClient(client);
+ provider.setUserDetailsService(dummyUserDetailsService());
+ return provider;
+ }
+
+ @Bean
+ public SpnegoEntryPoint spnegoEntryPoint() {
+ return new SpnegoEntryPoint("/login");
+ }
+
+ @Bean
+ public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(AuthenticationManager authenticationManager) {
+ SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter();
+ filter.setAuthenticationManager(authenticationManager);
+ return filter;
+ }
+
+ @Bean
+ public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
+ KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
+ provider.setTicketValidator(sunJaasKerberosTicketValidator());
+ provider.setUserDetailsService(dummyUserDetailsService());
+ return provider;
+ }
+
+ @Bean
+ public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
+ SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
+ ticketValidator.setServicePrincipal("HTTP/demo.kerberos.bealdung.com@baeldung.com");
+ ticketValidator.setKeyTabLocation(new FileSystemResource("baeldung.keytab"));
+ ticketValidator.setDebug(true);
+ return ticketValidator;
+ }
+
+ @Bean
+ public DummyUserDetailsService dummyUserDetailsService() {
+ return new DummyUserDetailsService();
+ }
+
+}
\ No newline at end of file
diff --git a/spring-security-kerberos/src/main/java/org/baeldung/security/DummyUserDetailsService.java b/spring-security-kerberos/src/main/java/org/baeldung/security/DummyUserDetailsService.java
new file mode 100644
index 0000000000..10d71fca8f
--- /dev/null
+++ b/spring-security-kerberos/src/main/java/org/baeldung/security/DummyUserDetailsService.java
@@ -0,0 +1,16 @@
+package org.baeldung.security;
+
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+
+public class DummyUserDetailsService implements UserDetailsService {
+
+ @Override
+ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+ return new User(username, "notUsed", true, true, true, true, AuthorityUtils.createAuthorityList("ROLE_USER"));
+ }
+
+}
\ No newline at end of file
diff --git a/vaadin/pom.xml b/vaadin/pom.xml
index d24b3dff1b..145a6af293 100644
--- a/vaadin/pom.xml
+++ b/vaadin/pom.xml
@@ -33,22 +33,6 @@
javax.servlet-api
provided
-
- com.vaadin
- vaadin-server
-
-
- com.vaadin
- vaadin-push
-
-
- com.vaadin
- vaadin-client-compiled
-
-
- com.vaadin
- vaadin-themes
-
org.springframework.boot
@@ -183,9 +167,9 @@
3.0.1
- 7.7.10
- 8.0.6
- 10.0.1
+ 10.0.11
+ 10.0.11
+ 10.0.11
9.3.9.v20160517
UTF-8
1.8
diff --git a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java b/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java
deleted file mode 100644
index 1b3733ad74..0000000000
--- a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java
+++ /dev/null
@@ -1,281 +0,0 @@
-package com.baeldung.introduction;
-
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.servlet.annotation.WebServlet;
-
-import com.vaadin.annotations.Push;
-import com.vaadin.annotations.Theme;
-import com.vaadin.annotations.VaadinServletConfiguration;
-import com.vaadin.data.Validator.InvalidValueException;
-import com.vaadin.data.fieldgroup.BeanFieldGroup;
-import com.vaadin.data.validator.StringLengthValidator;
-import com.vaadin.server.ExternalResource;
-import com.vaadin.server.FontAwesome;
-import com.vaadin.server.VaadinRequest;
-import com.vaadin.server.VaadinServlet;
-import com.vaadin.ui.Button;
-import com.vaadin.ui.CheckBox;
-import com.vaadin.ui.ComboBox;
-import com.vaadin.ui.DateField;
-import com.vaadin.ui.FormLayout;
-import com.vaadin.ui.Grid;
-import com.vaadin.ui.GridLayout;
-import com.vaadin.ui.HorizontalLayout;
-import com.vaadin.ui.InlineDateField;
-import com.vaadin.ui.Label;
-import com.vaadin.ui.Link;
-import com.vaadin.ui.ListSelect;
-import com.vaadin.ui.NativeButton;
-import com.vaadin.ui.NativeSelect;
-import com.vaadin.ui.Panel;
-import com.vaadin.ui.PasswordField;
-import com.vaadin.ui.RichTextArea;
-import com.vaadin.ui.TextArea;
-import com.vaadin.ui.TextField;
-import com.vaadin.ui.TwinColSelect;
-import com.vaadin.ui.UI;
-import com.vaadin.ui.VerticalLayout;
-
-@SuppressWarnings("serial")
-@Push
-@Theme("mytheme")
-public class VaadinUI extends UI {
-
- private Label currentTime;
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Override
- protected void init(VaadinRequest vaadinRequest) {
- final VerticalLayout verticalLayout = new VerticalLayout();
- verticalLayout.setSpacing(true);
- verticalLayout.setMargin(true);
- final GridLayout gridLayout = new GridLayout(3, 2);
- gridLayout.setSpacing(true);
- gridLayout.setMargin(true);
- final HorizontalLayout horizontalLayout = new HorizontalLayout();
- horizontalLayout.setSpacing(true);
- horizontalLayout.setMargin(true);
- final FormLayout formLayout = new FormLayout();
- formLayout.setSpacing(true);
- formLayout.setMargin(true);
- final GridLayout buttonLayout = new GridLayout(3, 5);
- buttonLayout.setMargin(true);
- buttonLayout.setSpacing(true);
-
- final Label label = new Label();
- label.setId("Label");
- label.setValue("Label Value");
- label.setCaption("Label");
- gridLayout.addComponent(label);
-
- final Link link = new Link("Baeldung", new ExternalResource("http://www.baeldung.com/"));
- link.setId("Link");
- link.setTargetName("_blank");
- gridLayout.addComponent(link);
-
- final TextField textField = new TextField();
- textField.setId("TextField");
- textField.setCaption("TextField:");
- textField.setValue("TextField Value");
- textField.setIcon(FontAwesome.USER);
- gridLayout.addComponent(textField);
-
- final TextArea textArea = new TextArea();
- textArea.setCaption("TextArea");
- textArea.setId("TextArea");
- textArea.setValue("TextArea Value");
- gridLayout.addComponent(textArea);
-
- final DateField dateField = new DateField("DateField", new Date(0));
- dateField.setId("DateField");
- gridLayout.addComponent(dateField);
-
- final PasswordField passwordField = new PasswordField();
- passwordField.setId("PasswordField");
- passwordField.setCaption("PasswordField:");
- passwordField.setValue("password");
- gridLayout.addComponent(passwordField);
-
- final RichTextArea richTextArea = new RichTextArea();
- richTextArea.setCaption("Rich Text Area");
- richTextArea.setValue("RichTextArea
");
- richTextArea.setSizeFull();
-
- Panel richTextPanel = new Panel();
- richTextPanel.setContent(richTextArea);
-
- final InlineDateField inlineDateField = new InlineDateField();
- inlineDateField.setValue(new Date(0));
- inlineDateField.setCaption("Inline Date Field");
- horizontalLayout.addComponent(inlineDateField);
-
- Button normalButton = new Button("Normal Button");
- normalButton.setId("NormalButton");
- normalButton.addClickListener(e -> {
- label.setValue("CLICK");
- });
- buttonLayout.addComponent(normalButton);
-
- Button tinyButton = new Button("Tiny Button");
- tinyButton.addStyleName("tiny");
- buttonLayout.addComponent(tinyButton);
-
- Button smallButton = new Button("Small Button");
- smallButton.addStyleName("small");
- buttonLayout.addComponent(smallButton);
-
- Button largeButton = new Button("Large Button");
- largeButton.addStyleName("large");
- buttonLayout.addComponent(largeButton);
-
- Button hugeButton = new Button("Huge Button");
- hugeButton.addStyleName("huge");
- buttonLayout.addComponent(hugeButton);
-
- Button disabledButton = new Button("Disabled Button");
- disabledButton.setDescription("This button cannot be clicked");
- disabledButton.setEnabled(false);
- buttonLayout.addComponent(disabledButton);
-
- Button dangerButton = new Button("Danger Button");
- dangerButton.addStyleName("danger");
- buttonLayout.addComponent(dangerButton);
-
- Button friendlyButton = new Button("Friendly Button");
- friendlyButton.addStyleName("friendly");
- buttonLayout.addComponent(friendlyButton);
-
- Button primaryButton = new Button("Primary Button");
- primaryButton.addStyleName("primary");
- buttonLayout.addComponent(primaryButton);
-
- NativeButton nativeButton = new NativeButton("Native Button");
- buttonLayout.addComponent(nativeButton);
-
- Button iconButton = new Button("Icon Button");
- iconButton.setIcon(FontAwesome.ALIGN_LEFT);
- buttonLayout.addComponent(iconButton);
-
- Button borderlessButton = new Button("BorderLess Button");
- borderlessButton.addStyleName("borderless");
- buttonLayout.addComponent(borderlessButton);
-
- Button linkButton = new Button("Link Button");
- linkButton.addStyleName("link");
- buttonLayout.addComponent(linkButton);
-
- Button quietButton = new Button("Quiet Button");
- quietButton.addStyleName("quiet");
- buttonLayout.addComponent(quietButton);
-
- horizontalLayout.addComponent(buttonLayout);
-
- final CheckBox checkbox = new CheckBox("CheckBox");
- checkbox.setValue(true);
- checkbox.addValueChangeListener(e -> checkbox.setValue(!checkbox.getValue()));
- formLayout.addComponent(checkbox);
-
- List numbers = new ArrayList();
- numbers.add("One");
- numbers.add("Ten");
- numbers.add("Eleven");
- ComboBox comboBox = new ComboBox("ComboBox");
- comboBox.addItems(numbers);
- formLayout.addComponent(comboBox);
-
- ListSelect listSelect = new ListSelect("ListSelect");
- listSelect.addItems(numbers);
- listSelect.setRows(2);
- formLayout.addComponent(listSelect);
-
- NativeSelect nativeSelect = new NativeSelect("NativeSelect");
- nativeSelect.addItems(numbers);
- formLayout.addComponent(nativeSelect);
-
- TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect");
- twinColSelect.addItems(numbers);
-
- Grid grid = new Grid("Grid");
- grid.setColumns("Column1", "Column2", "Column3");
- grid.addRow("Item1", "Item2", "Item3");
- grid.addRow("Item4", "Item5", "Item6");
-
- Panel panel = new Panel("Panel");
- panel.setContent(grid);
- panel.setSizeUndefined();
-
- Panel serverPushPanel = new Panel("Server Push");
- FormLayout timeLayout = new FormLayout();
- timeLayout.setSpacing(true);
- timeLayout.setMargin(true);
- currentTime = new Label("No TIME...");
- timeLayout.addComponent(currentTime);
- serverPushPanel.setContent(timeLayout);
- serverPushPanel.setSizeUndefined();
- ScheduledExecutorService scheduleExecutor = Executors.newScheduledThreadPool(1);
- Runnable task = () -> {
- currentTime.setValue("Current Time : " + Instant.now());
- };
- scheduleExecutor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);
-
- FormLayout dataBindingLayout = new FormLayout();
- dataBindingLayout.setSpacing(true);
- dataBindingLayout.setMargin(true);
-
- BindData bindData = new BindData("BindData");
- BeanFieldGroup beanFieldGroup = new BeanFieldGroup(BindData.class);
- beanFieldGroup.setItemDataSource(bindData);
- TextField bindedTextField = (TextField) beanFieldGroup.buildAndBind("BindName", "bindName");
- bindedTextField.setWidth("250px");
- dataBindingLayout.addComponent(bindedTextField);
-
- FormLayout validatorLayout = new FormLayout();
- validatorLayout.setSpacing(true);
- validatorLayout.setMargin(true);
-
- HorizontalLayout textValidatorLayout = new HorizontalLayout();
- textValidatorLayout.setSpacing(true);
- textValidatorLayout.setMargin(true);
-
- TextField stringValidator = new TextField();
- stringValidator.setNullSettingAllowed(true);
- stringValidator.setNullRepresentation("");
- stringValidator.addValidator(new StringLengthValidator("String must have 2-5 characters lenght", 2, 5, true));
- stringValidator.setValidationVisible(false);
- textValidatorLayout.addComponent(stringValidator);
- Button buttonStringValidator = new Button("Validate String");
- buttonStringValidator.addClickListener(e -> {
- try {
- stringValidator.setValidationVisible(false);
- stringValidator.validate();
- } catch (InvalidValueException err) {
- stringValidator.setValidationVisible(true);
- }
- });
- textValidatorLayout.addComponent(buttonStringValidator);
-
- validatorLayout.addComponent(textValidatorLayout);
- verticalLayout.addComponent(gridLayout);
- verticalLayout.addComponent(richTextPanel);
- verticalLayout.addComponent(horizontalLayout);
- verticalLayout.addComponent(formLayout);
- verticalLayout.addComponent(twinColSelect);
- verticalLayout.addComponent(panel);
- verticalLayout.addComponent(serverPushPanel);
- verticalLayout.addComponent(dataBindingLayout);
- verticalLayout.addComponent(validatorLayout);
- setContent(verticalLayout);
- }
-
- @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
- @VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false)
- public static class MyUIServlet extends VaadinServlet {
- }
-}