diff --git a/apache-libraries/pom.xml b/apache-libraries/pom.xml index ded10b939f..b4cf11b07d 100644 --- a/apache-libraries/pom.xml +++ b/apache-libraries/pom.xml @@ -133,6 +133,11 @@ jackson-databind ${jackson.version} + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + com.jayway.awaitility awaitility @@ -196,7 +201,6 @@ 1.8 1.8 1.8.2 - 1.7.25 2.19.0 3.9.0 1.1.2 diff --git a/apache-libraries/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java b/apache-libraries/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java index f2558635dc..77287066ac 100644 --- a/apache-libraries/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java +++ b/apache-libraries/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java @@ -10,7 +10,6 @@ import com.baeldung.apache.beam.intro.WordCount; public class WordCountUnitTest { @Test - // @Ignore public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() { boolean jobDone = WordCount.wordCount("src/test/resources/wordcount.txt", "target/output"); assertTrue(jobDone); diff --git a/apache-thrift/pom.xml b/apache-thrift/pom.xml index 9562ae7dfe..d2623f92e7 100644 --- a/apache-thrift/pom.xml +++ b/apache-thrift/pom.xml @@ -29,7 +29,7 @@ org.slf4j slf4j-simple - ${org.slf4j.slf4j-simple.version} + ${org.slf4j.version} test @@ -61,7 +61,6 @@ 0.10.0 0.1.11 - 1.7.12 3.0.0 diff --git a/core-groovy-2/pom.xml b/core-groovy-2/pom.xml index f8ef654293..89df666333 100644 --- a/core-groovy-2/pom.xml +++ b/core-groovy-2/pom.xml @@ -166,7 +166,6 @@ 2.4.0 1.1-groovy-2.4 1.1.3 - 1.2.3 2.5.7 3.1.0 3.8.0 diff --git a/core-java-modules/core-java-16/README.md b/core-java-modules/core-java-16/README.md index 760513189f..68215b3964 100644 --- a/core-java-modules/core-java-16/README.md +++ b/core-java-modules/core-java-16/README.md @@ -1,3 +1,4 @@ ### Relevant articles: - [Collect a Java Stream to an Immutable Collection](https://www.baeldung.com/java-stream-immutable-collection) +- [Guide to mapMulti in Stream API](https://www.baeldung.com/java-mapmulti) diff --git a/core-java-modules/core-java-arrays-operations-advanced/README.md b/core-java-modules/core-java-arrays-operations-advanced/README.md index 0e003b5cd9..f0d3d1fd93 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/README.md +++ b/core-java-modules/core-java-arrays-operations-advanced/README.md @@ -10,3 +10,4 @@ This module contains articles about advanced operations on arrays in Java. They - [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection) - [Comparing Arrays in Java](https://www.baeldung.com/java-comparing-arrays) - [Concatenate Two Arrays in Java](https://www.baeldung.com/java-concatenate-arrays) +- [Performance of System.arraycopy() vs. Arrays.copyOf()](https://www.baeldung.com/java-system-arraycopy-arrays-copyof-performance) diff --git a/core-java-modules/core-java-arrays-operations-advanced/pom.xml b/core-java-modules/core-java-arrays-operations-advanced/pom.xml index 5663a7d1ca..065f1930e2 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/pom.xml +++ b/core-java-modules/core-java-arrays-operations-advanced/pom.xml @@ -26,10 +26,50 @@ ${assertj-core.version} test + + + org.openjdk.jmh + jmh-core + ${jmh.version} + + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + 3.10.0 + 1.33 + + + + maven-assembly-plugin + + + jar-with-dependencies + + + + com.baeldung.copyarraymethodsperformance.BenchmarkRunner + + + + + + make-assembly + package + + single + + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/BenchmarkRunner.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/BenchmarkRunner.java new file mode 100644 index 0000000000..0adbcc1986 --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/BenchmarkRunner.java @@ -0,0 +1,11 @@ +package com.baeldung.copyarraymethodsperformance; + +public class BenchmarkRunner { + + public static void main(String[] args) throws Exception { + + org.openjdk.jmh.Main.main(args); + + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/ObjectsCopyBenchmark.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/ObjectsCopyBenchmark.java new file mode 100644 index 0000000000..6a492bf0d1 --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/ObjectsCopyBenchmark.java @@ -0,0 +1,42 @@ +package com.baeldung.copyarraymethodsperformance; + +import org.openjdk.jmh.annotations.*; + +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@State(Scope.Thread) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 10) +@Fork(1) +@Measurement(iterations = 100) +public class ObjectsCopyBenchmark { + + @Param({ "10", "1000000" }) + public int SIZE; + Integer[] src; + + @Setup + public void setup() { + Random r = new Random(); + src = new Integer[SIZE]; + + for (int i = 0; i < SIZE; i++) { + src[i] = r.nextInt(); + } + } + + @Benchmark + public Integer[] systemArrayCopyBenchmark() { + Integer[] target = new Integer[SIZE]; + System.arraycopy(src, 0, target, 0, SIZE); + return target; + } + + @Benchmark + public Integer[] arraysCopyOfBenchmark() { + return Arrays.copyOf(src, SIZE); + } +} diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/PrimitivesCopyBenchmark.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/PrimitivesCopyBenchmark.java new file mode 100644 index 0000000000..767e91a350 --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/copyarraymethodsperformance/PrimitivesCopyBenchmark.java @@ -0,0 +1,43 @@ +package com.baeldung.copyarraymethodsperformance; + +import org.openjdk.jmh.annotations.*; + +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@State(Scope.Thread) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 10) +@Fork(1) +@Measurement(iterations = 100) +public class PrimitivesCopyBenchmark { + + @Param({ "10", "1000000" }) + public int SIZE; + + int[] src; + + @Setup + public void setup() { + Random r = new Random(); + src = new int[SIZE]; + + for (int i = 0; i < SIZE; i++) { + src[i] = r.nextInt(); + } + } + + @Benchmark + public int[] systemArrayCopyBenchmark() { + int[] target = new int[SIZE]; + System.arraycopy(src, 0, target, 0, SIZE); + return target; + } + + @Benchmark + public int[] arraysCopyOfBenchmark() { + return Arrays.copyOf(src, SIZE); + } +} diff --git a/core-java-modules/core-java-networking-3/README.md b/core-java-modules/core-java-networking-3/README.md index 2e76ab5d51..0dc9ad9f70 100644 --- a/core-java-modules/core-java-networking-3/README.md +++ b/core-java-modules/core-java-networking-3/README.md @@ -8,4 +8,5 @@ This module contains articles about networking in Java - [Downloading Email Attachments in Java](https://www.baeldung.com/java-download-email-attachments) - [Connection Timeout vs. Read Timeout for Java Sockets](https://www.baeldung.com/java-socket-connection-read-timeout) - [Find Whether an IP Address Is in the Specified Range or Not in Java](https://www.baeldung.com/java-check-ip-address-range) +- [Find the IP Address of a Client Connected to a Server](https://www.baeldung.com/java-client-get-ip-address) - [[<-- Prev]](/core-java-modules/core-java-networking-2) diff --git a/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/clientaddress/ApplicationClient.java b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/clientaddress/ApplicationClient.java new file mode 100644 index 0000000000..498046904d --- /dev/null +++ b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/clientaddress/ApplicationClient.java @@ -0,0 +1,39 @@ +package com.baeldung.clientaddress; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; + +public class ApplicationClient { + + private Socket clientSocket; + private PrintWriter out; + private BufferedReader in; + + public void connect(String ip, int port) throws IOException { + clientSocket = new Socket(ip, port); + out = new PrintWriter(clientSocket.getOutputStream(), true); + in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + } + + public void sendGreetings(String msg) throws IOException { + out.println(msg); + String reply = in.readLine(); + System.out.println("Reply received from the server :: " + reply); + } + + public void disconnect() throws IOException { + in.close(); + out.close(); + clientSocket.close(); + } + + public static void main(String[] args) throws IOException { + ApplicationClient client = new ApplicationClient(); + client.connect(args[0], Integer.parseInt(args[1])); // IP address and port number of the server + client.sendGreetings(args[2]); // greetings message + client.disconnect(); + } +} diff --git a/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/clientaddress/ApplicationServer.java b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/clientaddress/ApplicationServer.java new file mode 100644 index 0000000000..ded4482b9a --- /dev/null +++ b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/clientaddress/ApplicationServer.java @@ -0,0 +1,51 @@ +package com.baeldung.clientaddress; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; + +public class ApplicationServer { + + private ServerSocket serverSocket; + private Socket connectedSocket; + private PrintWriter out; + private BufferedReader in; + + public void startServer(int port) throws IOException { + serverSocket = new ServerSocket(port); + connectedSocket = serverSocket.accept(); + + InetSocketAddress socketAddress = (InetSocketAddress) connectedSocket.getRemoteSocketAddress(); + String clientIpAddress = socketAddress.getAddress() + .getHostAddress(); + System.out.println("IP address of the connected client :: " + clientIpAddress); + + out = new PrintWriter(connectedSocket.getOutputStream(), true); + in = new BufferedReader(new InputStreamReader(connectedSocket.getInputStream())); + String msg = in.readLine(); + System.out.println("Message received from the client :: " + msg); + out.println("Hello Client !!"); + + closeIO(); + stopServer(); + } + + private void closeIO() throws IOException { + in.close(); + out.close(); + } + + private void stopServer() throws IOException { + connectedSocket.close(); + serverSocket.close(); + } + + public static void main(String[] args) throws IOException { + ApplicationServer server = new ApplicationServer(); + server.startServer(5000); + } +} diff --git a/core-java-modules/core-java-os/src/main/java/com/baeldung/java9/process/ProcessAPIEnhancements.java b/core-java-modules/core-java-os/src/main/java/com/baeldung/java9/process/ProcessAPIEnhancements.java new file mode 100644 index 0000000000..cb3c183062 --- /dev/null +++ b/core-java-modules/core-java-os/src/main/java/com/baeldung/java9/process/ProcessAPIEnhancements.java @@ -0,0 +1,101 @@ +package com.baeldung.java9.process; + +import java.io.IOException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.stream.Stream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ProcessAPIEnhancements { + + static Logger log = LoggerFactory.getLogger(ProcessAPIEnhancements.class); + + public static void main(String[] args) throws IOException, InterruptedException, ExecutionException { + infoOfCurrentProcess(); + infoOfLiveProcesses(); + infoOfSpawnProcess(); + infoOfExitCallback(); + infoOfChildProcess(); + } + + private static void infoOfCurrentProcess() { + ProcessHandle processHandle = ProcessHandle.current(); + ProcessHandle.Info processInfo = processHandle.info(); + + log.info("PID: " + processHandle.pid()); + log.info("Arguments: " + processInfo.arguments()); + log.info("Command: " + processInfo.command()); + log.info("Instant: " + processInfo.startInstant()); + log.info("Total CPU duration: " + processInfo.totalCpuDuration()); + log.info("User: " + processInfo.user()); + } + + private static void infoOfSpawnProcess() throws IOException { + + String javaCmd = ProcessUtils.getJavaCmd().getAbsolutePath(); + ProcessBuilder processBuilder = new ProcessBuilder(javaCmd, "-version"); + Process process = processBuilder.inheritIO().start(); + ProcessHandle processHandle = process.toHandle(); + ProcessHandle.Info processInfo = processHandle.info(); + + log.info("PID: " + processHandle.pid()); + log.info("Arguments: " + processInfo.arguments()); + log.info("Command: " + processInfo.command()); + log.info("Instant: " + processInfo.startInstant()); + log.info("Total CPU duration: " + processInfo.totalCpuDuration()); + log.info("User: " + processInfo.user()); + } + + private static void infoOfLiveProcesses() { + Stream liveProcesses = ProcessHandle.allProcesses(); + liveProcesses.filter(ProcessHandle::isAlive) + .forEach(ph -> { + log.info("PID: " + ph.pid()); + log.info("Instance: " + ph.info().startInstant()); + log.info("User: " + ph.info().user()); + }); + } + + private static void infoOfChildProcess() throws IOException { + int childProcessCount = 5; + for (int i = 0; i < childProcessCount; i++) { + String javaCmd = ProcessUtils.getJavaCmd() + .getAbsolutePath(); + ProcessBuilder processBuilder + = new ProcessBuilder(javaCmd, "-version"); + processBuilder.inheritIO().start(); + } + + Stream children = ProcessHandle.current() + .children(); + children.filter(ProcessHandle::isAlive) + .forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info() + .command())); + Stream descendants = ProcessHandle.current() + .descendants(); + descendants.filter(ProcessHandle::isAlive) + .forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info() + .command())); + } + + private static void infoOfExitCallback() throws IOException, InterruptedException, ExecutionException { + String javaCmd = ProcessUtils.getJavaCmd() + .getAbsolutePath(); + ProcessBuilder processBuilder + = new ProcessBuilder(javaCmd, "-version"); + Process process = processBuilder.inheritIO() + .start(); + ProcessHandle processHandle = process.toHandle(); + + log.info("PID: {} has started", processHandle.pid()); + CompletableFuture onProcessExit = processHandle.onExit(); + onProcessExit.get(); + log.info("Alive: " + processHandle.isAlive()); + onProcessExit.thenAccept(ph -> { + log.info("PID: {} has stopped", ph.pid()); + }); + } + +} diff --git a/core-java-modules/core-java-os/src/test/java/com/baeldung/java9/process/ProcessAPIEnhancementsUnitTest.java b/core-java-modules/core-java-os/src/test/java/com/baeldung/java9/process/ProcessAPIEnhancementsUnitTest.java deleted file mode 100644 index c81f060150..0000000000 --- a/core-java-modules/core-java-os/src/test/java/com/baeldung/java9/process/ProcessAPIEnhancementsUnitTest.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.baeldung.java9.process; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Stream; - -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Created by sanaulla on 2/23/2017. - */ - -public class ProcessAPIEnhancementsUnitTest { - - Logger log = LoggerFactory.getLogger(ProcessAPIEnhancementsUnitTest.class); - - // @Test - // OS / Java version dependent - public void givenCurrentProcess_whenInvokeGetInfo_thenSuccess() throws IOException { - ProcessHandle processHandle = ProcessHandle.current(); - ProcessHandle.Info processInfo = processHandle.info(); - assertNotNull(processHandle.pid()); - assertEquals(true, processInfo.arguments() - .isPresent()); - assertEquals(true, processInfo.command() - .isPresent()); - assertTrue(processInfo.command() - .get() - .contains("java")); - - assertEquals(true, processInfo.startInstant() - .isPresent()); - assertEquals(true, processInfo.totalCpuDuration() - .isPresent()); - assertEquals(true, processInfo.user() - .isPresent()); - } - - // @Test - // OS / Java version dependent - public void givenSpawnProcess_whenInvokeGetInfo_thenSuccess() throws IOException { - - String javaCmd = ProcessUtils.getJavaCmd() - .getAbsolutePath(); - ProcessBuilder processBuilder = new ProcessBuilder(javaCmd, "-version"); - Process process = processBuilder.inheritIO() - .start(); - ProcessHandle processHandle = process.toHandle(); - ProcessHandle.Info processInfo = processHandle.info(); - assertNotNull(processHandle.pid()); - assertEquals(true, processInfo.arguments() - .isPresent()); - assertEquals(true, processInfo.command() - .isPresent()); - assertTrue(processInfo.command() - .get() - .contains("java")); - assertEquals(true, processInfo.startInstant() - .isPresent()); - assertEquals(false, processInfo.totalCpuDuration() - .isPresent()); - assertEquals(true, processInfo.user() - .isPresent()); - } - - // @Test - // OS / Java version dependent - public void givenLiveProcesses_whenInvokeGetInfo_thenSuccess() { - Stream liveProcesses = ProcessHandle.allProcesses(); - liveProcesses.filter(ProcessHandle::isAlive) - .forEach(ph -> { - assertNotNull(ph.pid()); - assertEquals(true, ph.info() - .startInstant() - .isPresent()); - assertEquals(true, ph.info() - .user() - .isPresent()); - }); - } - - // @Test - // OS / Java version dependent - public void givenProcess_whenGetChildProcess_thenSuccess() throws IOException { - int childProcessCount = 5; - for (int i = 0; i < childProcessCount; i++) { - String javaCmd = ProcessUtils.getJavaCmd() - .getAbsolutePath(); - ProcessBuilder processBuilder - = new ProcessBuilder(javaCmd, "-version"); - processBuilder.inheritIO().start(); - } - - Stream children = ProcessHandle.current() - .children(); - children.filter(ProcessHandle::isAlive) - .forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info() - .command())); - Stream descendants = ProcessHandle.current() - .descendants(); - descendants.filter(ProcessHandle::isAlive) - .forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info() - .command())); - } - - // @Test - // OS / Java version dependent - public void givenProcess_whenAddExitCallback_thenSuccess() throws Exception { - String javaCmd = ProcessUtils.getJavaCmd() - .getAbsolutePath(); - ProcessBuilder processBuilder - = new ProcessBuilder(javaCmd, "-version"); - Process process = processBuilder.inheritIO() - .start(); - ProcessHandle processHandle = process.toHandle(); - - log.info("PID: {} has started", processHandle.pid()); - CompletableFuture onProcessExit = processHandle.onExit(); - onProcessExit.get(); - assertEquals(false, processHandle.isAlive()); - onProcessExit.thenAccept(ph -> { - log.info("PID: {} has stopped", ph.pid()); - }); - } - -} diff --git a/core-java-modules/core-java-security-3/README.md b/core-java-modules/core-java-security-3/README.md index 970faaac88..a37719964b 100644 --- a/core-java-modules/core-java-security-3/README.md +++ b/core-java-modules/core-java-security-3/README.md @@ -5,4 +5,5 @@ This module contains articles about core Java Security ### Relevant Articles: - [Secret Key and String Conversion in Java](https://www.baeldung.com/java-secret-key-to-string) +- [Enabling Unlimited Strength Cryptography in Java](https://www.baeldung.com/jce-enable-unlimited-strength) - More articles: [[<-- prev]](/core-java-modules/core-java-security-2) diff --git a/core-java-modules/core-java-security-3/src/test/java/com/baeldung/cryptography/CryptographyStrengthUnitTest.java b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/cryptography/CryptographyStrengthUnitTest.java new file mode 100644 index 0000000000..5d5c30dc34 --- /dev/null +++ b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/cryptography/CryptographyStrengthUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.cryptography; + +import org.junit.Test; + +import java.security.NoSuchAlgorithmException; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CryptographyStrengthUnitTest { + private static final int UNLIMITED_KEY_SIZE = 2147483647; + + @Test + public void whenDefaultCheck_thenUnlimitedReturned() throws NoSuchAlgorithmException { + int maxKeySize = javax.crypto.Cipher.getMaxAllowedKeyLength("AES"); + assertThat(maxKeySize).isEqualTo(UNLIMITED_KEY_SIZE); + } +} diff --git a/deeplearning4j/pom.xml b/deeplearning4j/pom.xml index f1f9b9fa7b..c63e67d573 100644 --- a/deeplearning4j/pom.xml +++ b/deeplearning4j/pom.xml @@ -39,12 +39,12 @@ org.slf4j slf4j-api - ${slf4j.version} + ${org.slf4j.version} org.slf4j slf4j-log4j12 - ${slf4j.version} + ${org.slf4j.version} @@ -62,7 +62,6 @@ 0.9.1 4.3.5 - 1.7.5 \ No newline at end of file diff --git a/ethereum/pom.xml b/ethereum/pom.xml index 4283714b98..b9a3870702 100644 --- a/ethereum/pom.xml +++ b/ethereum/pom.xml @@ -99,7 +99,7 @@ org.slf4j jcl-over-slf4j - ${slf4j.version} + ${org.slf4j.version} ch.qos.logback @@ -204,8 +204,6 @@ 1.5.6.RELEASE 2.21.0 2.4.0 - 1.2.3 - 1.7.25 2.0.4.RELEASE 3.1 diff --git a/jackson-modules/jackson-conversions-2/pom.xml b/jackson-modules/jackson-conversions-2/pom.xml index 799fcb106a..a498c8b4f8 100644 --- a/jackson-modules/jackson-conversions-2/pom.xml +++ b/jackson-modules/jackson-conversions-2/pom.xml @@ -24,7 +24,7 @@ com.fasterxml.jackson.datatype jackson-datatype-jsr310 - ${jackson-datatype.version} + ${jackson.version} @@ -52,7 +52,6 @@ 3.11.0 - 2.9.8 \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/java/com/baeldung/jackson/inheritance/SubTypeHandlingUnitTest.java b/jackson-modules/jackson/src/test/java/com/baeldung/jackson/inheritance/SubTypeHandlingUnitTest.java index b5b81fa4a3..8d6bc9ad6a 100644 --- a/jackson-modules/jackson/src/test/java/com/baeldung/jackson/inheritance/SubTypeHandlingUnitTest.java +++ b/jackson-modules/jackson/src/test/java/com/baeldung/jackson/inheritance/SubTypeHandlingUnitTest.java @@ -1,14 +1,22 @@ package com.baeldung.jackson.inheritance; +import static org.hamcrest.CoreMatchers.instanceOf; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import org.junit.Test; -import java.util.List; -import java.util.ArrayList; -import java.io.IOException; - +import com.baeldung.jackson.inheritance.SubTypeConstructorStructure.Car; +import com.baeldung.jackson.inheritance.SubTypeConstructorStructure.Fleet; +import com.baeldung.jackson.inheritance.SubTypeConstructorStructure.Truck; +import com.baeldung.jackson.inheritance.SubTypeConstructorStructure.Vehicle; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator; +import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator; public class SubTypeHandlingUnitTest { @Test @@ -23,21 +31,30 @@ public class SubTypeHandlingUnitTest { } @Test - public void givenSubType_whenNotUsingNoArgsConstructors_thenSucceed() throws IOException { + public void givenSubType_whenNotUsingNoArgsConstructors_thenSucceed() throws IOException { ObjectMapper mapper = new ObjectMapper(); - mapper.enableDefaultTyping(); + PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder() + .allowIfSubType("com.baeldung.jackson.inheritance") + .allowIfSubType("java.util.ArrayList") + .build(); + mapper.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.NON_FINAL); + + Car car = new Car("Mercedes-Benz", "S500", 5, 250.0); + Truck truck = new Truck("Isuzu", "NQR", 7500.0); - SubTypeConstructorStructure.Car car = new SubTypeConstructorStructure.Car("Mercedes-Benz", "S500", 5, 250.0); - SubTypeConstructorStructure.Truck truck = new SubTypeConstructorStructure.Truck("Isuzu", "NQR", 7500.0); - - List vehicles = new ArrayList<>(); + List vehicles = new ArrayList<>(); vehicles.add(car); vehicles.add(truck); - SubTypeConstructorStructure.Fleet serializedFleet = new SubTypeConstructorStructure.Fleet(); + Fleet serializedFleet = new Fleet(); serializedFleet.setVehicles(vehicles); String jsonDataString = mapper.writeValueAsString(serializedFleet); - mapper.readValue(jsonDataString, SubTypeConstructorStructure.Fleet.class); + mapper.readValue(jsonDataString, Fleet.class); + + Fleet deserializedFleet = mapper.readValue(jsonDataString, Fleet.class); + + assertThat(deserializedFleet.getVehicles().get(0), instanceOf(Car.class)); + assertThat(deserializedFleet.getVehicles().get(1), instanceOf(Truck.class)); } } \ No newline at end of file diff --git a/jackson-modules/jackson/src/test/java/com/baeldung/jackson/inheritance/TypeInfoInclusionUnitTest.java b/jackson-modules/jackson/src/test/java/com/baeldung/jackson/inheritance/TypeInfoInclusionUnitTest.java index 02297b9ee8..ca057edadc 100644 --- a/jackson-modules/jackson/src/test/java/com/baeldung/jackson/inheritance/TypeInfoInclusionUnitTest.java +++ b/jackson-modules/jackson/src/test/java/com/baeldung/jackson/inheritance/TypeInfoInclusionUnitTest.java @@ -10,12 +10,18 @@ import java.util.ArrayList; import java.io.IOException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator; +import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator; public class TypeInfoInclusionUnitTest { @Test public void givenTypeInfo_whenAnnotatingGlobally_thenTypesAreCorrectlyRecovered() throws IOException { ObjectMapper mapper = new ObjectMapper(); - mapper.enableDefaultTyping(); + PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder() + .allowIfSubType("com.baeldung.jackson.inheritance") + .allowIfSubType("java.util.ArrayList") + .build(); + mapper.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.NON_FINAL); TypeInfoStructure.Car car = new TypeInfoStructure.Car("Mercedes-Benz", "S500", 5, 250.0); TypeInfoStructure.Truck truck = new TypeInfoStructure.Truck("Isuzu", "NQR", 7500.0); diff --git a/json-2/README.md b/json-2/README.md index 64ca7e6449..aebc42c472 100644 --- a/json-2/README.md +++ b/json-2/README.md @@ -7,3 +7,4 @@ This module contains articles about JSON. - [Introduction to Jsoniter](https://www.baeldung.com/java-jsoniter) - [Introduction to Moshi Json](https://www.baeldung.com/java-json-moshi) - [Hypermedia Serialization With JSON-LD](https://www.baeldung.com/json-linked-data) +- [Generate a Java Class From JSON](https://www.baeldung.com/java-generate-class-from-json) diff --git a/json-2/src/main/java/com/baeldung/jsontojavaclass/JsonToJavaClassConversion.java b/json-2/src/main/java/com/baeldung/jsontojavaclass/JsonToJavaClassConversion.java index 65eecd0d38..1b18463856 100644 --- a/json-2/src/main/java/com/baeldung/jsontojavaclass/JsonToJavaClassConversion.java +++ b/json-2/src/main/java/com/baeldung/jsontojavaclass/JsonToJavaClassConversion.java @@ -17,7 +17,22 @@ import com.sun.codemodel.JCodeModel; public class JsonToJavaClassConversion { - public Object convertJsonToJavaClass(URL inputJson, File outputJavaClassDirectory, String packageName, String className) throws IOException { + public static void main(String[] args) { + String packageName = "com.baeldung.jsontojavaclass.pojo"; + String basePath = "src/main/resources"; + File inputJson = new File(basePath + File.separator + "input.json"); + File outputPojoDirectory = new File(basePath + File.separator + "convertedPojo"); + outputPojoDirectory.mkdirs(); + try { + new JsonToJavaClassConversion().convertJsonToJavaClass(inputJson.toURI().toURL(), outputPojoDirectory, packageName, inputJson.getName().replace(".json", "")); + } catch (IOException e) { + System.out.println("Encountered issue while converting to pojo: " + e.getMessage()); + e.printStackTrace(); + } + } + + + public void convertJsonToJavaClass(URL inputJsonUrl, File outputJavaClassDirectory, String packageName, String javaClassName) throws IOException { JCodeModel jcodeModel = new JCodeModel(); GenerationConfig config = new DefaultGenerationConfig() { @@ -33,10 +48,9 @@ public class JsonToJavaClassConversion { }; SchemaMapper mapper = new SchemaMapper(new RuleFactory(config, new Jackson2Annotator(config), new SchemaStore()), new SchemaGenerator()); - mapper.generate(jcodeModel, className, packageName, inputJson); + mapper.generate(jcodeModel, javaClassName, packageName, inputJsonUrl); jcodeModel.build(outputJavaClassDirectory); - return mapper; } } diff --git a/json-2/src/main/java/com/baeldung/jsontojavaclass/pojo/SamplePojo.java b/json-2/src/main/java/com/baeldung/jsontojavaclass/pojo/SamplePojo.java index 4c8a719de0..38ebb8a0f8 100644 --- a/json-2/src/main/java/com/baeldung/jsontojavaclass/pojo/SamplePojo.java +++ b/json-2/src/main/java/com/baeldung/jsontojavaclass/pojo/SamplePojo.java @@ -5,9 +5,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - import javax.annotation.Generated; - import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -16,7 +14,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; @JsonInclude(JsonInclude.Include.NON_NULL) -@JsonPropertyOrder({ "name", "area", "author", "id", "salary", "topics" }) +@JsonPropertyOrder({ + "name", + "area", + "author", + "id", + "salary", + "topics" +}) @Generated("jsonschema2pojo") public class SamplePojo { @@ -143,40 +148,37 @@ public class SamplePojo { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append(SamplePojo.class.getName()) - .append('@') - .append(Integer.toHexString(System.identityHashCode(this))) - .append('['); + sb.append(SamplePojo.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('['); sb.append("name"); sb.append('='); - sb.append(((this.name == null) ? "" : this.name)); + sb.append(((this.name == null)?"":this.name)); sb.append(','); sb.append("area"); sb.append('='); - sb.append(((this.area == null) ? "" : this.area)); + sb.append(((this.area == null)?"":this.area)); sb.append(','); sb.append("author"); sb.append('='); - sb.append(((this.author == null) ? "" : this.author)); + sb.append(((this.author == null)?"":this.author)); sb.append(','); sb.append("id"); sb.append('='); - sb.append(((this.id == null) ? "" : this.id)); + sb.append(((this.id == null)?"":this.id)); sb.append(','); sb.append("salary"); sb.append('='); - sb.append(((this.salary == null) ? "" : this.salary)); + sb.append(((this.salary == null)?"":this.salary)); sb.append(','); sb.append("topics"); sb.append('='); - sb.append(((this.topics == null) ? "" : this.topics)); + sb.append(((this.topics == null)?"":this.topics)); sb.append(','); sb.append("additionalProperties"); sb.append('='); - sb.append(((this.additionalProperties == null) ? "" : this.additionalProperties)); + sb.append(((this.additionalProperties == null)?"":this.additionalProperties)); sb.append(','); - if (sb.charAt((sb.length() - 1)) == ',') { - sb.setCharAt((sb.length() - 1), ']'); + if (sb.charAt((sb.length()- 1)) == ',') { + sb.setCharAt((sb.length()- 1), ']'); } else { sb.append(']'); } @@ -186,13 +188,13 @@ public class SamplePojo { @Override public int hashCode() { int result = 1; - result = ((result * 31) + ((this.area == null) ? 0 : this.area.hashCode())); - result = ((result * 31) + ((this.author == null) ? 0 : this.author.hashCode())); - result = ((result * 31) + ((this.topics == null) ? 0 : this.topics.hashCode())); - result = ((result * 31) + ((this.name == null) ? 0 : this.name.hashCode())); - result = ((result * 31) + ((this.id == null) ? 0 : this.id.hashCode())); - result = ((result * 31) + ((this.additionalProperties == null) ? 0 : this.additionalProperties.hashCode())); - result = ((result * 31) + ((this.salary == null) ? 0 : this.salary.hashCode())); + result = ((result* 31)+((this.area == null)? 0 :this.area.hashCode())); + result = ((result* 31)+((this.author == null)? 0 :this.author.hashCode())); + result = ((result* 31)+((this.topics == null)? 0 :this.topics.hashCode())); + result = ((result* 31)+((this.name == null)? 0 :this.name.hashCode())); + result = ((result* 31)+((this.id == null)? 0 :this.id.hashCode())); + result = ((result* 31)+((this.additionalProperties == null)? 0 :this.additionalProperties.hashCode())); + result = ((result* 31)+((this.salary == null)? 0 :this.salary.hashCode())); return result; } @@ -205,10 +207,7 @@ public class SamplePojo { return false; } SamplePojo rhs = ((SamplePojo) other); - return ((((((((this.area == rhs.area) || ((this.area != null) && this.area.equals(rhs.area))) && ((this.author == rhs.author) || ((this.author != null) && this.author.equals(rhs.author)))) - && ((this.topics == rhs.topics) || ((this.topics != null) && this.topics.equals(rhs.topics)))) && ((this.name == rhs.name) || ((this.name != null) && this.name.equals(rhs.name)))) - && ((this.id == rhs.id) || ((this.id != null) && this.id.equals(rhs.id)))) && ((this.additionalProperties == rhs.additionalProperties) || ((this.additionalProperties != null) && this.additionalProperties.equals(rhs.additionalProperties)))) - && ((this.salary == rhs.salary) || ((this.salary != null) && this.salary.equals(rhs.salary)))); + return ((((((((this.area == rhs.area)||((this.area!= null)&&this.area.equals(rhs.area)))&&((this.author == rhs.author)||((this.author!= null)&&this.author.equals(rhs.author))))&&((this.topics == rhs.topics)||((this.topics!= null)&&this.topics.equals(rhs.topics))))&&((this.name == rhs.name)||((this.name!= null)&&this.name.equals(rhs.name))))&&((this.id == rhs.id)||((this.id!= null)&&this.id.equals(rhs.id))))&&((this.additionalProperties == rhs.additionalProperties)||((this.additionalProperties!= null)&&this.additionalProperties.equals(rhs.additionalProperties))))&&((this.salary == rhs.salary)||((this.salary!= null)&&this.salary.equals(rhs.salary)))); } } diff --git a/json-2/src/main/resources/convertedPojo/com/baeldung/jsontojavaclass/pojo/Address.java b/json-2/src/main/resources/convertedPojo/com/baeldung/jsontojavaclass/pojo/Address.java new file mode 100644 index 0000000000..e3d901edf4 --- /dev/null +++ b/json-2/src/main/resources/convertedPojo/com/baeldung/jsontojavaclass/pojo/Address.java @@ -0,0 +1,119 @@ + +package com.baeldung.jsontojavaclass.pojo; + +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "city", + "country" +}) +@Generated("jsonschema2pojo") +public class Address { + + @JsonProperty("city") + private String city; + @JsonProperty("country") + private String country; + @JsonIgnore + private Map additionalProperties = new HashMap(); + + @JsonProperty("city") + public String getCity() { + return city; + } + + @JsonProperty("city") + public void setCity(String city) { + this.city = city; + } + + public Address withCity(String city) { + this.city = city; + return this; + } + + @JsonProperty("country") + public String getCountry() { + return country; + } + + @JsonProperty("country") + public void setCountry(String country) { + this.country = country; + } + + public Address withCountry(String country) { + this.country = country; + return this; + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + public Address withAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + return this; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(Address.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('['); + sb.append("city"); + sb.append('='); + sb.append(((this.city == null)?"":this.city)); + sb.append(','); + sb.append("country"); + sb.append('='); + sb.append(((this.country == null)?"":this.country)); + sb.append(','); + sb.append("additionalProperties"); + sb.append('='); + sb.append(((this.additionalProperties == null)?"":this.additionalProperties)); + sb.append(','); + if (sb.charAt((sb.length()- 1)) == ',') { + sb.setCharAt((sb.length()- 1), ']'); + } else { + sb.append(']'); + } + return sb.toString(); + } + + @Override + public int hashCode() { + int result = 1; + result = ((result* 31)+((this.country == null)? 0 :this.country.hashCode())); + result = ((result* 31)+((this.additionalProperties == null)? 0 :this.additionalProperties.hashCode())); + result = ((result* 31)+((this.city == null)? 0 :this.city.hashCode())); + return result; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof Address) == false) { + return false; + } + Address rhs = ((Address) other); + return ((((this.country == rhs.country)||((this.country!= null)&&this.country.equals(rhs.country)))&&((this.additionalProperties == rhs.additionalProperties)||((this.additionalProperties!= null)&&this.additionalProperties.equals(rhs.additionalProperties))))&&((this.city == rhs.city)||((this.city!= null)&&this.city.equals(rhs.city)))); + } + +} diff --git a/json-2/src/main/resources/convertedPojo/com/baeldung/jsontojavaclass/pojo/Input.java b/json-2/src/main/resources/convertedPojo/com/baeldung/jsontojavaclass/pojo/Input.java new file mode 100644 index 0000000000..19bee8db4d --- /dev/null +++ b/json-2/src/main/resources/convertedPojo/com/baeldung/jsontojavaclass/pojo/Input.java @@ -0,0 +1,213 @@ + +package com.baeldung.jsontojavaclass.pojo; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "name", + "area", + "author", + "id", + "topics", + "address" +}) +@Generated("jsonschema2pojo") +public class Input { + + @JsonProperty("name") + private String name; + @JsonProperty("area") + private String area; + @JsonProperty("author") + private String author; + @JsonProperty("id") + private Integer id; + @JsonProperty("topics") + private List topics = new ArrayList(); + @JsonProperty("address") + private Address address; + @JsonIgnore + private Map additionalProperties = new HashMap(); + + @JsonProperty("name") + public String getName() { + return name; + } + + @JsonProperty("name") + public void setName(String name) { + this.name = name; + } + + public Input withName(String name) { + this.name = name; + return this; + } + + @JsonProperty("area") + public String getArea() { + return area; + } + + @JsonProperty("area") + public void setArea(String area) { + this.area = area; + } + + public Input withArea(String area) { + this.area = area; + return this; + } + + @JsonProperty("author") + public String getAuthor() { + return author; + } + + @JsonProperty("author") + public void setAuthor(String author) { + this.author = author; + } + + public Input withAuthor(String author) { + this.author = author; + return this; + } + + @JsonProperty("id") + public Integer getId() { + return id; + } + + @JsonProperty("id") + public void setId(Integer id) { + this.id = id; + } + + public Input withId(Integer id) { + this.id = id; + return this; + } + + @JsonProperty("topics") + public List getTopics() { + return topics; + } + + @JsonProperty("topics") + public void setTopics(List topics) { + this.topics = topics; + } + + public Input withTopics(List topics) { + this.topics = topics; + return this; + } + + @JsonProperty("address") + public Address getAddress() { + return address; + } + + @JsonProperty("address") + public void setAddress(Address address) { + this.address = address; + } + + public Input withAddress(Address address) { + this.address = address; + return this; + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + public Input withAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + return this; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(Input.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('['); + sb.append("name"); + sb.append('='); + sb.append(((this.name == null)?"":this.name)); + sb.append(','); + sb.append("area"); + sb.append('='); + sb.append(((this.area == null)?"":this.area)); + sb.append(','); + sb.append("author"); + sb.append('='); + sb.append(((this.author == null)?"":this.author)); + sb.append(','); + sb.append("id"); + sb.append('='); + sb.append(((this.id == null)?"":this.id)); + sb.append(','); + sb.append("topics"); + sb.append('='); + sb.append(((this.topics == null)?"":this.topics)); + sb.append(','); + sb.append("address"); + sb.append('='); + sb.append(((this.address == null)?"":this.address)); + sb.append(','); + sb.append("additionalProperties"); + sb.append('='); + sb.append(((this.additionalProperties == null)?"":this.additionalProperties)); + sb.append(','); + if (sb.charAt((sb.length()- 1)) == ',') { + sb.setCharAt((sb.length()- 1), ']'); + } else { + sb.append(']'); + } + return sb.toString(); + } + + @Override + public int hashCode() { + int result = 1; + result = ((result* 31)+((this.area == null)? 0 :this.area.hashCode())); + result = ((result* 31)+((this.address == null)? 0 :this.address.hashCode())); + result = ((result* 31)+((this.author == null)? 0 :this.author.hashCode())); + result = ((result* 31)+((this.topics == null)? 0 :this.topics.hashCode())); + result = ((result* 31)+((this.name == null)? 0 :this.name.hashCode())); + result = ((result* 31)+((this.id == null)? 0 :this.id.hashCode())); + result = ((result* 31)+((this.additionalProperties == null)? 0 :this.additionalProperties.hashCode())); + return result; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof Input) == false) { + return false; + } + Input rhs = ((Input) other); + return ((((((((this.area == rhs.area)||((this.area!= null)&&this.area.equals(rhs.area)))&&((this.address == rhs.address)||((this.address!= null)&&this.address.equals(rhs.address))))&&((this.author == rhs.author)||((this.author!= null)&&this.author.equals(rhs.author))))&&((this.topics == rhs.topics)||((this.topics!= null)&&this.topics.equals(rhs.topics))))&&((this.name == rhs.name)||((this.name!= null)&&this.name.equals(rhs.name))))&&((this.id == rhs.id)||((this.id!= null)&&this.id.equals(rhs.id))))&&((this.additionalProperties == rhs.additionalProperties)||((this.additionalProperties!= null)&&this.additionalProperties.equals(rhs.additionalProperties)))); + } + +} diff --git a/json-2/src/main/resources/input.json b/json-2/src/main/resources/input.json new file mode 100644 index 0000000000..22706ede53 --- /dev/null +++ b/json-2/src/main/resources/input.json @@ -0,0 +1,16 @@ +{ + "name": "Baeldung", + "area": "tech blogs", + "author": "Eugen", + "id": 32134, + "topics": [ + "java", + "kotlin", + "cs", + "linux" + ], + "address": { + "city": "Bucharest", + "country": "Romania" + } +} \ No newline at end of file diff --git a/json-2/src/test/java/com/baeldung/jsontojavaclass/JsonToJavaClassConversionUnitTest.java b/json-2/src/test/java/com/baeldung/jsontojavaclass/JsonToJavaClassConversionUnitTest.java index 8dbfb14b45..f8000fa6fb 100644 --- a/json-2/src/test/java/com/baeldung/jsontojavaclass/JsonToJavaClassConversionUnitTest.java +++ b/json-2/src/test/java/com/baeldung/jsontojavaclass/JsonToJavaClassConversionUnitTest.java @@ -3,6 +3,7 @@ package com.baeldung.jsontojavaclass; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; +import java.util.Arrays; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -21,17 +22,16 @@ class JsonToJavaClassConversionUnitTest { File inputJson = new File(jsonPath + "sample_input.json"); // create the local directory for generating the Java Class file - String outputPath = "src/main/java/"; + String outputPath = "src/test/resources/"; File outputJavaClassDirectory = new File(outputPath); - outputJavaClassDirectory.mkdirs(); - String className = "SamplePojo"; + String javaClassName = "SamplePojo"; - Object object = jsonToJavaConversion.convertJsonToJavaClass(inputJson.toURI() - .toURL(), outputJavaClassDirectory, packageName, className); - System.out.println(object); + jsonToJavaConversion.convertJsonToJavaClass(inputJson.toURI() + .toURL(), outputJavaClassDirectory, packageName, javaClassName); - Assertions.assertNotNull(object); + File outputJavaClassPath = new File(outputPath + packageName.replace(".", "/")); + Assertions.assertTrue(Arrays.stream(outputJavaClassPath.listFiles()).peek(System.out::println).anyMatch(file -> (javaClassName+".java").equalsIgnoreCase(file.getName()))); } diff --git a/json-2/src/test/resources/com/baeldung/jsontojavaclass/pojo/SamplePojo.java b/json-2/src/test/resources/com/baeldung/jsontojavaclass/pojo/SamplePojo.java new file mode 100644 index 0000000000..38ebb8a0f8 --- /dev/null +++ b/json-2/src/test/resources/com/baeldung/jsontojavaclass/pojo/SamplePojo.java @@ -0,0 +1,213 @@ + +package com.baeldung.jsontojavaclass.pojo; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "name", + "area", + "author", + "id", + "salary", + "topics" +}) +@Generated("jsonschema2pojo") +public class SamplePojo { + + @JsonProperty("name") + private String name; + @JsonProperty("area") + private String area; + @JsonProperty("author") + private String author; + @JsonProperty("id") + private Integer id; + @JsonProperty("salary") + private Integer salary; + @JsonProperty("topics") + private List topics = new ArrayList(); + @JsonIgnore + private Map additionalProperties = new HashMap(); + + @JsonProperty("name") + public String getName() { + return name; + } + + @JsonProperty("name") + public void setName(String name) { + this.name = name; + } + + public SamplePojo withName(String name) { + this.name = name; + return this; + } + + @JsonProperty("area") + public String getArea() { + return area; + } + + @JsonProperty("area") + public void setArea(String area) { + this.area = area; + } + + public SamplePojo withArea(String area) { + this.area = area; + return this; + } + + @JsonProperty("author") + public String getAuthor() { + return author; + } + + @JsonProperty("author") + public void setAuthor(String author) { + this.author = author; + } + + public SamplePojo withAuthor(String author) { + this.author = author; + return this; + } + + @JsonProperty("id") + public Integer getId() { + return id; + } + + @JsonProperty("id") + public void setId(Integer id) { + this.id = id; + } + + public SamplePojo withId(Integer id) { + this.id = id; + return this; + } + + @JsonProperty("salary") + public Integer getSalary() { + return salary; + } + + @JsonProperty("salary") + public void setSalary(Integer salary) { + this.salary = salary; + } + + public SamplePojo withSalary(Integer salary) { + this.salary = salary; + return this; + } + + @JsonProperty("topics") + public List getTopics() { + return topics; + } + + @JsonProperty("topics") + public void setTopics(List topics) { + this.topics = topics; + } + + public SamplePojo withTopics(List topics) { + this.topics = topics; + return this; + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + public SamplePojo withAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + return this; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(SamplePojo.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('['); + sb.append("name"); + sb.append('='); + sb.append(((this.name == null)?"":this.name)); + sb.append(','); + sb.append("area"); + sb.append('='); + sb.append(((this.area == null)?"":this.area)); + sb.append(','); + sb.append("author"); + sb.append('='); + sb.append(((this.author == null)?"":this.author)); + sb.append(','); + sb.append("id"); + sb.append('='); + sb.append(((this.id == null)?"":this.id)); + sb.append(','); + sb.append("salary"); + sb.append('='); + sb.append(((this.salary == null)?"":this.salary)); + sb.append(','); + sb.append("topics"); + sb.append('='); + sb.append(((this.topics == null)?"":this.topics)); + sb.append(','); + sb.append("additionalProperties"); + sb.append('='); + sb.append(((this.additionalProperties == null)?"":this.additionalProperties)); + sb.append(','); + if (sb.charAt((sb.length()- 1)) == ',') { + sb.setCharAt((sb.length()- 1), ']'); + } else { + sb.append(']'); + } + return sb.toString(); + } + + @Override + public int hashCode() { + int result = 1; + result = ((result* 31)+((this.area == null)? 0 :this.area.hashCode())); + result = ((result* 31)+((this.author == null)? 0 :this.author.hashCode())); + result = ((result* 31)+((this.topics == null)? 0 :this.topics.hashCode())); + result = ((result* 31)+((this.name == null)? 0 :this.name.hashCode())); + result = ((result* 31)+((this.id == null)? 0 :this.id.hashCode())); + result = ((result* 31)+((this.additionalProperties == null)? 0 :this.additionalProperties.hashCode())); + result = ((result* 31)+((this.salary == null)? 0 :this.salary.hashCode())); + return result; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof SamplePojo) == false) { + return false; + } + SamplePojo rhs = ((SamplePojo) other); + return ((((((((this.area == rhs.area)||((this.area!= null)&&this.area.equals(rhs.area)))&&((this.author == rhs.author)||((this.author!= null)&&this.author.equals(rhs.author))))&&((this.topics == rhs.topics)||((this.topics!= null)&&this.topics.equals(rhs.topics))))&&((this.name == rhs.name)||((this.name!= null)&&this.name.equals(rhs.name))))&&((this.id == rhs.id)||((this.id!= null)&&this.id.equals(rhs.id))))&&((this.additionalProperties == rhs.additionalProperties)||((this.additionalProperties!= null)&&this.additionalProperties.equals(rhs.additionalProperties))))&&((this.salary == rhs.salary)||((this.salary!= null)&&this.salary.equals(rhs.salary)))); + } + +} diff --git a/kubernetes/k8s-admission-controller/README.md b/kubernetes/k8s-admission-controller/README.md index c446ab403d..9c824d76b3 100644 --- a/kubernetes/k8s-admission-controller/README.md +++ b/kubernetes/k8s-admission-controller/README.md @@ -1,3 +1,4 @@ ## Relevant Articles: - [Creating a Kubertes Admission Controller in Java](https://www.baeldung.com/java-kubernetes-admission-controller) +- [Access Control Models](https://www.baeldung.com/java-access-control-models) diff --git a/libraries-data-2/pom.xml b/libraries-data-2/pom.xml index cce2e57d22..75b2cc962d 100644 --- a/libraries-data-2/pom.xml +++ b/libraries-data-2/pom.xml @@ -104,12 +104,12 @@ org.slf4j slf4j-api - ${slf4j.version} + ${org.slf4j.version} org.slf4j slf4j-log4j12 - ${slf4j.version} + ${org.slf4j.version} com.univocity @@ -161,7 +161,6 @@ 4.0.0 1.1.0 3.6.2 - 1.7.25 3.0.0 2.8.4 29.0-jre diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index 717ee802db..c5ad08448f 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -108,7 +108,7 @@ org.slf4j slf4j-api - ${slf4j.version} + ${org.slf4j.version} org.apache.storm @@ -173,7 +173,6 @@ 3.8.4 0.15.0 2.2.0 - 1.7.25 1.6.0.1 diff --git a/libraries-io/src/main/java/com/baeldung/java/io/zip4j/CreateSplitZipFile.java b/libraries-io/src/main/java/com/baeldung/java/io/zip4j/CreateSplitZipFile.java index cc39bc9dd2..a7ecd7946e 100644 --- a/libraries-io/src/main/java/com/baeldung/java/io/zip4j/CreateSplitZipFile.java +++ b/libraries-io/src/main/java/com/baeldung/java/io/zip4j/CreateSplitZipFile.java @@ -1,22 +1,23 @@ package com.baeldung.java.io.zip4j; import net.lingala.zip4j.ZipFile; -import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.model.ZipParameters; import net.lingala.zip4j.model.enums.EncryptionMethod; import java.io.File; +import java.io.IOException; import java.util.Arrays; public class CreateSplitZipFile { - public static void main(String[] args) throws ZipException { + public static void main(String[] args) throws IOException { ZipParameters zipParameters = new ZipParameters(); zipParameters.setEncryptFiles(true); zipParameters.setEncryptionMethod(EncryptionMethod.AES); ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray()); - int splitLength = 1024 * 1024 * 10; //10MB + int splitLength = 1024 * 1024 * 10; // 10MB zipFile.createSplitZipFile(Arrays.asList(new File("aFile.txt")), zipParameters, true, splitLength); zipFile.createSplitZipFileFromFolder(new File("/users/folder_to_add"), zipParameters, true, splitLength); + zipFile.close(); } } diff --git a/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ExtractAllFile.java b/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ExtractAllFile.java index 10e7ddd339..924d80a921 100644 --- a/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ExtractAllFile.java +++ b/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ExtractAllFile.java @@ -1,12 +1,14 @@ package com.baeldung.java.io.zip4j; +import java.io.IOException; + import net.lingala.zip4j.ZipFile; -import net.lingala.zip4j.exception.ZipException; public class ExtractAllFile { - public static void main(String[] args) throws ZipException { + public static void main(String[] args) throws IOException { ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray()); zipFile.extractAll("/destination_directory"); + zipFile.close(); } } diff --git a/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ExtractSingleFile.java b/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ExtractSingleFile.java index 4cf466d02b..ad79557a37 100644 --- a/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ExtractSingleFile.java +++ b/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ExtractSingleFile.java @@ -1,12 +1,14 @@ package com.baeldung.java.io.zip4j; +import java.io.IOException; + import net.lingala.zip4j.ZipFile; -import net.lingala.zip4j.exception.ZipException; public class ExtractSingleFile { - public static void main(String[] args) throws ZipException { + public static void main(String[] args) throws IOException { ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray()); zipFile.extractFile("aFile.txt", "/destination_directory"); + zipFile.close(); } } diff --git a/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ZipFolder.java b/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ZipFolder.java index 4d89e8665f..ed25494083 100644 --- a/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ZipFolder.java +++ b/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ZipFolder.java @@ -1,19 +1,20 @@ package com.baeldung.java.io.zip4j; import net.lingala.zip4j.ZipFile; -import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.model.ZipParameters; import net.lingala.zip4j.model.enums.EncryptionMethod; import java.io.File; +import java.io.IOException; public class ZipFolder { - public static void main(String[] args) throws ZipException { + public static void main(String[] args) throws IOException { ZipParameters zipParameters = new ZipParameters(); zipParameters.setEncryptFiles(true); zipParameters.setEncryptionMethod(EncryptionMethod.AES); ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray()); zipFile.addFolder(new File("/users/folder_to_add"), zipParameters); + zipFile.close(); } } diff --git a/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ZipMultiFile.java b/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ZipMultiFile.java index dcb860ef92..081d207294 100644 --- a/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ZipMultiFile.java +++ b/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ZipMultiFile.java @@ -1,27 +1,34 @@ package com.baeldung.java.io.zip4j; import net.lingala.zip4j.ZipFile; -import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.model.ZipParameters; import net.lingala.zip4j.model.enums.EncryptionMethod; import java.io.File; +import java.io.IOException; import java.util.Arrays; import java.util.List; public class ZipMultiFile { - public static void main(String[] args) throws ZipException { + public static void main(String[] args) throws IOException { ZipParameters zipParameters = new ZipParameters(); zipParameters.setEncryptFiles(true); zipParameters.setEncryptionMethod(EncryptionMethod.AES); - List filesToAdd = Arrays.asList( - new File("aFile.txt"), - new File("bFile.txt") - ); + File firstFile = new File("aFile.txt"); + File secondFile = new File("bFile.txt"); + if (!firstFile.exists()) { + firstFile.createNewFile(); + } + if (!secondFile.exists()) { + secondFile.createNewFile(); + } + + List filesToAdd = Arrays.asList(firstFile, secondFile); ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray()); zipFile.addFiles(filesToAdd, zipParameters); + zipFile.close(); } } diff --git a/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ZipSingleFile.java b/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ZipSingleFile.java index a5f600df47..d0947afa2e 100644 --- a/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ZipSingleFile.java +++ b/libraries-io/src/main/java/com/baeldung/java/io/zip4j/ZipSingleFile.java @@ -1,21 +1,27 @@ package com.baeldung.java.io.zip4j; import net.lingala.zip4j.ZipFile; -import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.model.ZipParameters; import net.lingala.zip4j.model.enums.CompressionLevel; import net.lingala.zip4j.model.enums.EncryptionMethod; import java.io.File; +import java.io.IOException; public class ZipSingleFile { - public static void main(String[] args) throws ZipException { + public static void main(String[] args) throws IOException { ZipParameters zipParameters = new ZipParameters(); zipParameters.setEncryptFiles(true); zipParameters.setCompressionLevel(CompressionLevel.HIGHER); zipParameters.setEncryptionMethod(EncryptionMethod.AES); ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray()); - zipFile.addFile(new File("aFile.txt")); + + File fileToAdd = new File("aFile.txt"); + if (!fileToAdd.exists()) { + fileToAdd.createNewFile(); + } + zipFile.addFile(fileToAdd); + zipFile.close(); } } diff --git a/logging-modules/logback/pom.xml b/logging-modules/logback/pom.xml index 6d32025d94..512dc9e5a3 100644 --- a/logging-modules/logback/pom.xml +++ b/logging-modules/logback/pom.xml @@ -69,7 +69,6 @@ - 1.2.3 0.1.5 3.3.5 1.4.7 diff --git a/maven-modules/maven-parent-pom-resolution/README.md b/maven-modules/maven-parent-pom-resolution/README.md index 6f72b5e70b..b315b2f626 100644 --- a/maven-modules/maven-parent-pom-resolution/README.md +++ b/maven-modules/maven-parent-pom-resolution/README.md @@ -1,3 +1,3 @@ ### Relevant Articles: -- [Understanding the "relativePath" Tag - Maven Parent POM Resolution At A Glance](https://www.baeldung.com/maven-relativepath) +- [Understanding Maven’s “relativePath” Tag for a Parent POM](https://www.baeldung.com/maven-relativepath) diff --git a/maven-modules/maven-parent-pom-resolution/project-a/project-b/pom.xml b/maven-modules/maven-parent-pom-resolution/aggregator/module1/pom.xml similarity index 69% rename from maven-modules/maven-parent-pom-resolution/project-a/project-b/pom.xml rename to maven-modules/maven-parent-pom-resolution/aggregator/module1/pom.xml index e3f5239efe..01b522748f 100644 --- a/maven-modules/maven-parent-pom-resolution/project-a/project-b/pom.xml +++ b/maven-modules/maven-parent-pom-resolution/aggregator/module1/pom.xml @@ -3,11 +3,11 @@ 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"> 4.0.0 - project-b + module1 - com.baeldung - project-a - 1.0-SNAPSHOT + com.baeldung.maven-parent-pom-resolution + aggregator + 1.0.0-SNAPSHOT pom diff --git a/maven-modules/maven-parent-pom-resolution/project-a/project-c/project-d/pom.xml b/maven-modules/maven-parent-pom-resolution/aggregator/module2/module3/pom.xml similarity index 75% rename from maven-modules/maven-parent-pom-resolution/project-a/project-c/project-d/pom.xml rename to maven-modules/maven-parent-pom-resolution/aggregator/module2/module3/pom.xml index 973e44eb1f..da0193be10 100644 --- a/maven-modules/maven-parent-pom-resolution/project-a/project-c/project-d/pom.xml +++ b/maven-modules/maven-parent-pom-resolution/aggregator/module2/module3/pom.xml @@ -3,11 +3,11 @@ 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"> 4.0.0 - project-d + module3 - com.baeldung - project-a - 1.0-SNAPSHOT + com.baeldung.maven-parent-pom-resolution + aggregator + 1.0.0-SNAPSHOT ../../pom.xml diff --git a/maven-modules/maven-parent-pom-resolution/project-a/project-c/pom.xml b/maven-modules/maven-parent-pom-resolution/aggregator/module2/pom.xml similarity index 62% rename from maven-modules/maven-parent-pom-resolution/project-a/project-c/pom.xml rename to maven-modules/maven-parent-pom-resolution/aggregator/module2/pom.xml index 3c7f70ae20..bf9c89ecf4 100644 --- a/maven-modules/maven-parent-pom-resolution/project-a/project-c/pom.xml +++ b/maven-modules/maven-parent-pom-resolution/aggregator/module2/pom.xml @@ -3,18 +3,18 @@ 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"> 4.0.0 - project-c + module2 - com.baeldung - project-b - 1.0-SNAPSHOT - ../project-b/pom.xml + com.baeldung.maven-parent-pom-resolution + module1 + 1.0.0-SNAPSHOT + ../module1/pom.xml pom - project-d + module3 diff --git a/maven-modules/maven-parent-pom-resolution/project-a/pom.xml b/maven-modules/maven-parent-pom-resolution/aggregator/pom.xml similarity index 72% rename from maven-modules/maven-parent-pom-resolution/project-a/pom.xml rename to maven-modules/maven-parent-pom-resolution/aggregator/pom.xml index 2d53a36d84..0067dfc009 100644 --- a/maven-modules/maven-parent-pom-resolution/project-a/pom.xml +++ b/maven-modules/maven-parent-pom-resolution/aggregator/pom.xml @@ -3,18 +3,19 @@ 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"> 4.0.0 - project-a + com.baeldung.maven-parent-pom-resolution + aggregator com.baeldung maven-parent-pom-resolution - 1.0-SNAPSHOT + 1.0.0-SNAPSHOT pom - project-b - project-c + module1 + module2 diff --git a/maven-modules/maven-parent-pom-resolution/pom.xml b/maven-modules/maven-parent-pom-resolution/pom.xml index 62e3946723..d5a96c0998 100644 --- a/maven-modules/maven-parent-pom-resolution/pom.xml +++ b/maven-modules/maven-parent-pom-resolution/pom.xml @@ -5,11 +5,11 @@ 4.0.0 com.baeldung maven-parent-pom-resolution - 1.0-SNAPSHOT + 1.0.0-SNAPSHOT pom - project-a + aggregator diff --git a/micronaut/pom.xml b/micronaut/pom.xml index 196218d856..e9b5a0409f 100644 --- a/micronaut/pom.xml +++ b/micronaut/pom.xml @@ -61,7 +61,7 @@ ch.qos.logback logback-classic - ${lombok.version} + ${logback.version} runtime @@ -145,7 +145,6 @@ 1.0.0.RC2 1.8 1.3.2 - 1.2.3 3.1.6.RELEASE 3.7.0 3.1.0 diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index accbc2df96..2e520640ec 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -81,7 +81,7 @@ 3.3.0 1.0.22.RELEASE - 2.5.1 + 2.5.4 1.9.1 3.4.0 diff --git a/pdf/pom.xml b/pdf/pom.xml index fb9508156e..6bd1d97402 100644 --- a/pdf/pom.xml +++ b/pdf/pom.xml @@ -71,6 +71,26 @@ flying-saucer-pdf ${flying-saucer-pdf.version} + + org.xhtmlrenderer + flying-saucer-pdf-openpdf + ${flying-saucer-pdf-openpdf.version} + + + org.jsoup + jsoup + ${jsoup.version} + + + com.openhtmltopdf + openhtmltopdf-core + ${open-html-pdf-core.version} + + + com.openhtmltopdf + openhtmltopdf-pdfbox + ${open-html-pdfbox.version} + @@ -93,6 +113,10 @@ 3.15 3.0.11.RELEASE 9.1.20 + 1.0.6 + 1.0.6 + 9.1.22 + 1.14.2 \ No newline at end of file diff --git a/pdf/src/main/java/com/baeldung/pdf/openpdf/CustomElementFactoryImpl.java b/pdf/src/main/java/com/baeldung/pdf/openpdf/CustomElementFactoryImpl.java new file mode 100644 index 0000000000..d8256a68f7 --- /dev/null +++ b/pdf/src/main/java/com/baeldung/pdf/openpdf/CustomElementFactoryImpl.java @@ -0,0 +1,56 @@ +package com.baeldung.pdf.openpdf; + +import java.io.FileInputStream; +import java.io.InputStream; + +import org.apache.commons.io.IOUtils; +import org.w3c.dom.Element; +import org.xhtmlrenderer.extend.FSImage; +import org.xhtmlrenderer.extend.ReplacedElement; +import org.xhtmlrenderer.extend.ReplacedElementFactory; +import org.xhtmlrenderer.extend.UserAgentCallback; +import org.xhtmlrenderer.layout.LayoutContext; +import org.xhtmlrenderer.pdf.ITextFSImage; +import org.xhtmlrenderer.pdf.ITextImageElement; +import org.xhtmlrenderer.render.BlockBox; +import org.xhtmlrenderer.simple.extend.FormSubmissionListener; + +import com.lowagie.text.Image; + +public class CustomElementFactoryImpl implements ReplacedElementFactory { + @Override + public ReplacedElement createReplacedElement(LayoutContext lc, BlockBox box, UserAgentCallback uac, int cssWidth, int cssHeight) { + Element e = box.getElement(); + String nodeName = e.getNodeName(); + if (nodeName.equals("img")) { + String imagePath = e.getAttribute("src"); + try { + InputStream input = new FileInputStream("src/main/resources/" + imagePath); + byte[] bytes = IOUtils.toByteArray(input); + Image image = Image.getInstance(bytes); + FSImage fsImage = new ITextFSImage(image); + if (cssWidth != -1 || cssHeight != -1) { + fsImage.scale(cssWidth, cssHeight); + } else { + fsImage.scale(2000, 1000); + } + return new ITextImageElement(fsImage); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + return null; + } + + @Override + public void reset() { + } + + @Override + public void remove(Element e) { + } + + @Override + public void setFormSubmissionListener(FormSubmissionListener listener) { + } +} \ No newline at end of file diff --git a/pdf/src/main/java/com/baeldung/pdf/openpdf/Html2PdfUsingFlyingSaucer.java b/pdf/src/main/java/com/baeldung/pdf/openpdf/Html2PdfUsingFlyingSaucer.java new file mode 100644 index 0000000000..927d85a4cb --- /dev/null +++ b/pdf/src/main/java/com/baeldung/pdf/openpdf/Html2PdfUsingFlyingSaucer.java @@ -0,0 +1,53 @@ +package com.baeldung.pdf.openpdf; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.xhtmlrenderer.layout.SharedContext; +import org.xhtmlrenderer.pdf.ITextRenderer; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +public class Html2PdfUsingFlyingSaucer { + + private static final String HTML_INPUT = "src/main/resources/htmlforopenpdf.html"; + private static final String PDF_OUTPUT = "src/main/resources/html2pdf.pdf"; + + public static void main(String[] args) { + try { + Html2PdfUsingFlyingSaucer htmlToPdf = new Html2PdfUsingFlyingSaucer(); + htmlToPdf.generateHtmlToPdf(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void generateHtmlToPdf() throws Exception { + File inputHTML = new File(HTML_INPUT); + Document inputHtml = createWellFormedHtml(inputHTML); + File outputPdf = new File(PDF_OUTPUT); + xhtmlToPdf(inputHtml, outputPdf); + } + + private Document createWellFormedHtml(File inputHTML) throws IOException { + Document document = Jsoup.parse(inputHTML, "UTF-8"); + document.outputSettings() + .syntax(Document.OutputSettings.Syntax.xml); + return document; + } + + private void xhtmlToPdf(Document xhtml, File outputPdf) throws Exception { + try (OutputStream outputStream = new FileOutputStream(outputPdf)) { + ITextRenderer renderer = new ITextRenderer(); + SharedContext sharedContext = renderer.getSharedContext(); + sharedContext.setPrint(true); + sharedContext.setInteractive(false); + sharedContext.setReplacedElementFactory(new CustomElementFactoryImpl()); + renderer.setDocumentFromString(xhtml.html()); + renderer.layout(); + renderer.createPDF(outputStream); + } + } +} diff --git a/pdf/src/main/java/com/baeldung/pdf/openpdf/Html2PdfUsingOpenHtml.java b/pdf/src/main/java/com/baeldung/pdf/openpdf/Html2PdfUsingOpenHtml.java new file mode 100644 index 0000000000..bc83da6102 --- /dev/null +++ b/pdf/src/main/java/com/baeldung/pdf/openpdf/Html2PdfUsingOpenHtml.java @@ -0,0 +1,55 @@ +package com.baeldung.pdf.openpdf; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.FileSystems; + +import org.jsoup.Jsoup; +import org.jsoup.helper.W3CDom; +import org.jsoup.nodes.Document; + +import com.openhtmltopdf.pdfboxout.PdfRendererBuilder; + +public class Html2PdfUsingOpenHtml { + + private static final String HTML_INPUT = "src/main/resources/htmlforopenpdf.html"; + private static final String PDF_OUTPUT = "src/main/resources/html2pdf.pdf"; + + public static void main(String[] args) { + try { + Html2PdfUsingOpenHtml htmlToPdf = new Html2PdfUsingOpenHtml(); + htmlToPdf.generateHtmlToPdf(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void generateHtmlToPdf() throws IOException { + File inputHTML = new File(HTML_INPUT); + Document doc = createWellFormedHtml(inputHTML); + xhtmlToPdf(doc, PDF_OUTPUT); + } + + private Document createWellFormedHtml(File inputHTML) throws IOException { + Document document = Jsoup.parse(inputHTML, "UTF-8"); + document.outputSettings() + .syntax(Document.OutputSettings.Syntax.xml); + return document; + } + + private void xhtmlToPdf(Document doc, String outputPdf) throws IOException { + try (OutputStream os = new FileOutputStream(outputPdf)) { + String baseUri = FileSystems.getDefault() + .getPath("src/main/resources/") + .toUri() + .toString(); + PdfRendererBuilder builder = new PdfRendererBuilder(); + builder.withUri(outputPdf); + builder.toStream(os); + builder.withW3cDocument(new W3CDom().fromJsoup(doc), baseUri); + builder.run(); + } + } +} diff --git a/pdf/src/main/resources/html2pdf.pdf b/pdf/src/main/resources/html2pdf.pdf new file mode 100644 index 0000000000..877ff4cacd Binary files /dev/null and b/pdf/src/main/resources/html2pdf.pdf differ diff --git a/pdf/src/main/resources/htmlforopenpdf.html b/pdf/src/main/resources/htmlforopenpdf.html new file mode 100644 index 0000000000..ae39965c87 --- /dev/null +++ b/pdf/src/main/resources/htmlforopenpdf.html @@ -0,0 +1,26 @@ + + + + + + + + Hello Baeldung! + + + + This is the tutorial to convert html to pdf. + + + + \ No newline at end of file diff --git a/pdf/src/main/resources/style.css b/pdf/src/main/resources/style.css new file mode 100644 index 0000000000..381ffadf00 --- /dev/null +++ b/pdf/src/main/resources/style.css @@ -0,0 +1,6 @@ +.myclass{ + font-family: Helvetica, sans-serif; + font-size:25; + font-weight: normal; + color: blue; +} \ No newline at end of file diff --git a/persistence-modules/hibernate-libraries/pom.xml b/persistence-modules/hibernate-libraries/pom.xml index 19537156aa..7d552b262d 100644 --- a/persistence-modules/hibernate-libraries/pom.xml +++ b/persistence-modules/hibernate-libraries/pom.xml @@ -77,7 +77,7 @@ org.slf4j slf4j-api - ${slf4j.version} + ${org.slf4j.version} provided true @@ -174,12 +174,10 @@ 3.27.0-GA 2.3.1 2.0.0 - 1.2.3 3.0.2 3.8.1 3.8.1 8.0.19 - 1.7.30 2.1.3.RELEASE diff --git a/persistence-modules/java-jpa-3/README.md b/persistence-modules/java-jpa-3/README.md index d517c55d7a..202c97a830 100644 --- a/persistence-modules/java-jpa-3/README.md +++ b/persistence-modules/java-jpa-3/README.md @@ -14,3 +14,4 @@ This module contains articles about the Java Persistence API (JPA) in Java. - [How to Return Multiple Entities In JPA Query](https://www.baeldung.com/jpa-return-multiple-entities) - [Defining Unique Constraints in JPA](https://www.baeldung.com/jpa-unique-constraints) - [How to Check Field Existence in MongoDB?](https://www.baeldung.com/mongodb-check-field-exists) +- [Connecting to a Specific Schema in JDBC](https://www.baeldung.com/jdbc-connect-to-schema) diff --git a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/boot/daos/InventoryRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/boot/daos/InventoryRepositoryIntegrationTest.java index 22e2c81739..e4bd3dabff 100644 --- a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/boot/daos/InventoryRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/boot/daos/InventoryRepositoryIntegrationTest.java @@ -3,20 +3,23 @@ package com.baeldung.boot.daos; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.math.BigDecimal; +import java.util.Optional; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; import com.baeldung.Application; import com.baeldung.boot.domain.MerchandiseEntity; @RunWith(SpringRunner.class) -@SpringBootTest(classes=Application.class) +@SpringBootTest(classes = Application.class) public class InventoryRepositoryIntegrationTest { private static final String ORIGINAL_TITLE = "Pair of Pants"; @@ -58,4 +61,28 @@ public class InventoryRepositoryIntegrationTest { assertEquals(BigDecimal.TEN, result.getPrice()); assertEquals(UPDATED_BRAND, result.getBrand()); } + + @Test + @Transactional + public void shouldUpdateExistingEntryInDBWithoutSave() { + MerchandiseEntity pants = new MerchandiseEntity(ORIGINAL_TITLE, BigDecimal.ONE); + pants = repository.save(pants); + + Long originalId = pants.getId(); + + // Update using setters + pants.setTitle(UPDATED_TITLE); + pants.setPrice(BigDecimal.TEN); + pants.setBrand(UPDATED_BRAND); + + Optional resultOp = repository.findById(originalId); + + assertTrue(resultOp.isPresent()); + MerchandiseEntity result = resultOp.get(); + + assertEquals(originalId, result.getId()); + assertEquals(UPDATED_TITLE, result.getTitle()); + assertEquals(BigDecimal.TEN, result.getPrice()); + assertEquals(UPDATED_BRAND, result.getBrand()); + } } diff --git a/persistence-modules/spring-data-mongodb-reactive/README.md b/persistence-modules/spring-data-mongodb-reactive/README.md index 0931161700..4fbdb87785 100644 --- a/persistence-modules/spring-data-mongodb-reactive/README.md +++ b/persistence-modules/spring-data-mongodb-reactive/README.md @@ -8,5 +8,3 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles - [Spring Data Reactive Repositories with MongoDB](https://www.baeldung.com/spring-data-mongodb-reactive) - [Spring Data MongoDB Tailable Cursors](https://www.baeldung.com/spring-data-mongodb-tailable-cursors) -- [A Quick Look at R2DBC with Spring Data](https://www.baeldung.com/spring-data-r2dbc) -- [Spring Data Reactive Repositories with Couchbase](https://www.baeldung.com/spring-data-reactive-couchbase) diff --git a/pom.xml b/pom.xml index 059c6dae25..b94283277b 100644 --- a/pom.xml +++ b/pom.xml @@ -1410,7 +1410,7 @@ 1.2 2.3.1 1.2 - 2.11.1 + 2.12.4 1.4 1.2.0 5.2.0 diff --git a/restx/pom.xml b/restx/pom.xml index ee25c88047..ac0ff36376 100644 --- a/restx/pom.xml +++ b/restx/pom.xml @@ -99,7 +99,7 @@ ch.qos.logback logback-classic - ${logback-classic.version} + ${logback.version} io.restx @@ -149,7 +149,6 @@ 0.35-rc4 - 1.2.3 diff --git a/spf4j/spf4j-aspects-app/pom.xml b/spf4j/spf4j-aspects-app/pom.xml index a44ee805fb..c4940b9c97 100644 --- a/spf4j/spf4j-aspects-app/pom.xml +++ b/spf4j/spf4j-aspects-app/pom.xml @@ -99,7 +99,6 @@ 8.9.0 - 1.7.21 3.8.0 3.1.1 diff --git a/spf4j/spf4j-core-app/pom.xml b/spf4j/spf4j-core-app/pom.xml index 1f9be97854..28c104afe1 100644 --- a/spf4j/spf4j-core-app/pom.xml +++ b/spf4j/spf4j-core-app/pom.xml @@ -105,7 +105,6 @@ 8.9.0 - 1.7.21 3.8.0 3.1.1 diff --git a/spring-5-data-reactive/README.md b/spring-5-data-reactive/README.md index 0931161700..ecb6d01267 100644 --- a/spring-5-data-reactive/README.md +++ b/spring-5-data-reactive/README.md @@ -6,7 +6,5 @@ This module contains articles about reactive Spring 5 Data The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles -- [Spring Data Reactive Repositories with MongoDB](https://www.baeldung.com/spring-data-mongodb-reactive) -- [Spring Data MongoDB Tailable Cursors](https://www.baeldung.com/spring-data-mongodb-tailable-cursors) - [A Quick Look at R2DBC with Spring Data](https://www.baeldung.com/spring-data-r2dbc) - [Spring Data Reactive Repositories with Couchbase](https://www.baeldung.com/spring-data-reactive-couchbase) diff --git a/spring-5-reactive-client/src/main/java/com/baeldung/reactive/controller/UploadController.java b/spring-5-reactive-client/src/main/java/com/baeldung/reactive/controller/UploadController.java new file mode 100644 index 0000000000..08d6ff55ef --- /dev/null +++ b/spring-5-reactive-client/src/main/java/com/baeldung/reactive/controller/UploadController.java @@ -0,0 +1,30 @@ +package com.baeldung.reactive.controller; + + +import com.baeldung.reactive.service.ReactiveUploadService; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import reactor.core.publisher.Mono; + + +@RestController +public class UploadController { + final ReactiveUploadService uploadService; + + public UploadController(ReactiveUploadService uploadService) { + this.uploadService = uploadService; + } + + @PostMapping(path = "/upload") + @ResponseBody + public Mono uploadPdf(@RequestParam("file") final MultipartFile multipartFile) { + return uploadService.uploadPdf(multipartFile.getResource()); + } + + @PostMapping(path = "/upload/multipart") + @ResponseBody + public Mono uploadMultipart(@RequestParam("file") final MultipartFile multipartFile) { + return uploadService.uploadMultipart(multipartFile); + } +} diff --git a/spring-5-reactive-client/src/main/java/com/baeldung/reactive/exception/ServiceException.java b/spring-5-reactive-client/src/main/java/com/baeldung/reactive/exception/ServiceException.java new file mode 100644 index 0000000000..cd639ec1f9 --- /dev/null +++ b/spring-5-reactive-client/src/main/java/com/baeldung/reactive/exception/ServiceException.java @@ -0,0 +1,8 @@ +package com.baeldung.reactive.exception; + +public class ServiceException extends RuntimeException{ + + public ServiceException(String message) { + super(message); + } +} diff --git a/spring-5-reactive-client/src/main/java/com/baeldung/reactive/service/ReactiveUploadService.java b/spring-5-reactive-client/src/main/java/com/baeldung/reactive/service/ReactiveUploadService.java new file mode 100644 index 0000000000..a12d54960a --- /dev/null +++ b/spring-5-reactive-client/src/main/java/com/baeldung/reactive/service/ReactiveUploadService.java @@ -0,0 +1,66 @@ +package com.baeldung.reactive.service; + + +import com.baeldung.reactive.exception.ServiceException; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.client.MultipartBodyBuilder; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.UriComponentsBuilder; +import reactor.core.publisher.Mono; + +import java.net.URI; + +@Service +public class ReactiveUploadService { + + private final WebClient webClient; + private static final String EXTERNAL_UPLOAD_URL = "http://localhost:8080/external/upload"; + + public ReactiveUploadService(final WebClient webClient) { + this.webClient = webClient; + } + + + public Mono uploadPdf(final Resource resource) { + + final URI url = UriComponentsBuilder.fromHttpUrl(EXTERNAL_UPLOAD_URL).build().toUri(); + Mono httpStatusMono = webClient.post() + .uri(url) + .contentType(MediaType.APPLICATION_PDF) + .body(BodyInserters.fromResource(resource)) + .exchangeToMono(response -> { + if (response.statusCode().equals(HttpStatus.OK)) { + return response.bodyToMono(HttpStatus.class).thenReturn(response.statusCode()); + } else { + throw new ServiceException("Error uploading file"); + } + }); + return httpStatusMono; + } + + + public Mono uploadMultipart(final MultipartFile multipartFile) { + final URI url = UriComponentsBuilder.fromHttpUrl(EXTERNAL_UPLOAD_URL).build().toUri(); + + final MultipartBodyBuilder builder = new MultipartBodyBuilder(); + builder.part("file", multipartFile.getResource()); + + Mono httpStatusMono = webClient.post() + .uri(url) + .contentType(MediaType.MULTIPART_FORM_DATA) + .body(BodyInserters.fromMultipartData(builder.build())) + .exchangeToMono(response -> { + if (response.statusCode().equals(HttpStatus.OK)) { + return response.bodyToMono(HttpStatus.class).thenReturn(response.statusCode()); + } else { + throw new ServiceException("Error uploading file"); + } + }); + return httpStatusMono; + } +} diff --git a/spring-5-reactive-client/src/test/java/com/baeldung/reactive/service/ReactiveUploadServiceUnitTest.java b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/service/ReactiveUploadServiceUnitTest.java new file mode 100644 index 0000000000..40c1e40d92 --- /dev/null +++ b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/service/ReactiveUploadServiceUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.reactive.service; + +import org.junit.jupiter.api.Test; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpStatus; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class ReactiveUploadServiceUnitTest { + + private static final String BASE_URL = "http://localhost:8080/external/upload"; + + final WebClient webClientMock = WebClient.builder().baseUrl(BASE_URL) + .exchangeFunction(clientRequest -> Mono.just(ClientResponse.create(HttpStatus.OK) + .header("content-type", "application/json") + .build())) + .build(); + + private final ReactiveUploadService tested = new ReactiveUploadService(webClientMock); + + @Test + void givenAPdf_whenUploadingWithWebClient_thenOK() { + final Resource file = mock(Resource.class); + + final Mono result = tested.uploadPdf(file); + final HttpStatus status = result.block(); + + assertThat(status).isEqualTo(HttpStatus.OK); + } + + @Test + void givenAMultipartPdf_whenUploadingWithWebClient_thenOK() { + final Resource file = mock(Resource.class); + final MultipartFile multipartFile = mock(MultipartFile.class); + when(multipartFile.getResource()).thenReturn(file); + + final Mono result = tested.uploadMultipart(multipartFile); + final HttpStatus status = result.block(); + + assertThat(status).isEqualTo(HttpStatus.OK); + } +} \ No newline at end of file diff --git a/spring-5-webflux/pom.xml b/spring-5-webflux/pom.xml index ad1a66943c..b37e93ded8 100644 --- a/spring-5-webflux/pom.xml +++ b/spring-5-webflux/pom.xml @@ -65,8 +65,4 @@ - - 2.3.3.RELEASE - - \ No newline at end of file diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientConfiguration.java b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientConfiguration.java index abfe2e7807..2e2c309240 100644 --- a/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientConfiguration.java +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/rsocket/client/ClientConfiguration.java @@ -1,30 +1,29 @@ package com.baeldung.spring.rsocket.client; -import io.rsocket.RSocket; -import io.rsocket.RSocketFactory; -import io.rsocket.frame.decoder.PayloadDecoder; -import io.rsocket.transport.netty.client.TcpClientTransport; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.rsocket.RSocketRequester; -import org.springframework.messaging.rsocket.RSocketStrategies; import org.springframework.util.MimeTypeUtils; +import reactor.util.retry.Retry; + +import java.time.Duration; @Configuration public class ClientConfiguration { @Bean - public RSocket rSocket() { - return RSocketFactory.connect() - .mimeType(MimeTypeUtils.APPLICATION_JSON_VALUE, MimeTypeUtils.APPLICATION_JSON_VALUE) - .frameDecoder(PayloadDecoder.ZERO_COPY) - .transport(TcpClientTransport.create(7000)) - .start() - .block(); - } + public RSocketRequester getRSocketRequester(){ - @Bean - RSocketRequester rSocketRequester(RSocketStrategies rSocketStrategies) { - return RSocketRequester.wrap(rSocket(), MimeTypeUtils.APPLICATION_JSON, MimeTypeUtils.APPLICATION_JSON, rSocketStrategies); + RSocketRequester.Builder builder = RSocketRequester.builder(); + + return builder + .rsocketConnector( + rSocketConnector -> + rSocketConnector.reconnect( + Retry.fixedDelay(2, Duration.ofSeconds(2)) + ) + ) + .dataMimeType(MimeTypeUtils.APPLICATION_JSON) + .tcp("localhost", 7000); } } diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/serverconfig/CustomNettyWebServerFactory.java b/spring-5-webflux/src/main/java/com/baeldung/spring/serverconfig/CustomNettyWebServerFactory.java index f9de3b4006..2d11a51160 100644 --- a/spring-5-webflux/src/main/java/com/baeldung/spring/serverconfig/CustomNettyWebServerFactory.java +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/serverconfig/CustomNettyWebServerFactory.java @@ -25,12 +25,9 @@ public class CustomNettyWebServerFactory { @Override public HttpServer apply(HttpServer httpServer) { - EventLoopGroup parentGroup = new NioEventLoopGroup(); - EventLoopGroup childGroup = new NioEventLoopGroup(); - return httpServer - .tcpConfiguration(tcpServer -> tcpServer.bootstrap( - serverBootstrap -> serverBootstrap.group(parentGroup, childGroup).channel(NioServerSocketChannel.class) - )); + EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); + eventLoopGroup.register(new NioServerSocketChannel()); + return httpServer.runOn(eventLoopGroup); } } } diff --git a/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/server/MarketDataRSocketControllerLiveTest.java b/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/server/MarketDataRSocketControllerLiveTest.java index 40ddc732ac..98d604b178 100644 --- a/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/server/MarketDataRSocketControllerLiveTest.java +++ b/spring-5-webflux/src/test/java/com/baeldung/spring/rsocket/server/MarketDataRSocketControllerLiveTest.java @@ -1,15 +1,8 @@ package com.baeldung.spring.rsocket.server; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.verify; - import com.baeldung.spring.rsocket.model.MarketData; import com.baeldung.spring.rsocket.model.MarketDataRequest; import io.rsocket.RSocket; -import io.rsocket.RSocketFactory; -import io.rsocket.frame.decoder.PayloadDecoder; -import io.rsocket.transport.netty.client.TcpClientTransport; -import java.time.Duration; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -23,6 +16,12 @@ import org.springframework.messaging.rsocket.RSocketStrategies; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.MimeTypeUtils; +import reactor.util.retry.Retry; + +import java.time.Duration; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; @RunWith(SpringRunner.class) @SpringBootTest @@ -81,12 +80,16 @@ public class MarketDataRSocketControllerLiveTest { @Bean @Lazy public RSocket rSocket() { - return RSocketFactory.connect() - .mimeType(MimeTypeUtils.APPLICATION_JSON_VALUE, MimeTypeUtils.APPLICATION_JSON_VALUE) - .frameDecoder(PayloadDecoder.ZERO_COPY) - .transport(TcpClientTransport.create(7000)) - .start() - .block(); + + RSocketRequester.Builder builder = RSocketRequester.builder(); + + return builder + .rsocketConnector( + rSocketConnector -> + rSocketConnector.reconnect(Retry.fixedDelay(2, Duration.ofSeconds(2)))) + .dataMimeType(MimeTypeUtils.APPLICATION_JSON) + .tcp("localhost", 7000) + .rsocket(); } @Bean diff --git a/spring-aop/src/main/java/com/baeldung/joinpoint/ArticleService.java b/spring-aop/src/main/java/com/baeldung/joinpoint/ArticleService.java new file mode 100644 index 0000000000..5a6b5ce63a --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/joinpoint/ArticleService.java @@ -0,0 +1,32 @@ +package com.baeldung.joinpoint; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; + +import static java.util.stream.Collectors.toList; + +@Service +public class ArticleService { + + public List getArticleList() { + return Arrays.asList( + "Article 1", + "Article 2" + ); + } + + public List getArticleList(String startsWithFilter) { + if (StringUtils.isBlank(startsWithFilter)) { + throw new IllegalArgumentException("startsWithFilter can't be blank"); + } + + return getArticleList() + .stream() + .filter(a -> a.startsWith(startsWithFilter)) + .collect(toList()); + } + +} diff --git a/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAfterThrowingAspect.java b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAfterThrowingAspect.java new file mode 100644 index 0000000000..a1f991e90d --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAfterThrowingAspect.java @@ -0,0 +1,27 @@ +package com.baeldung.joinpoint; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; + +import java.util.logging.Logger; + +@Aspect +@Component +public class JoinPointAfterThrowingAspect { + + private static final java.util.logging.Logger log = Logger.getLogger(JoinPointAfterThrowingAspect.class.getName()); + + @Pointcut("execution(* com.baeldung.joinpoint.ArticleService.getArticleList(..))") + public void articleListPointcut() { } + + @AfterThrowing( + pointcut = "articleListPointcut()", + throwing = "e" + ) + public void logExceptions(JoinPoint jp, Exception e) { + log.severe(e.getMessage()); + } +} diff --git a/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAroundCacheAspect.java b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAroundCacheAspect.java new file mode 100644 index 0000000000..dbf2b2e1e4 --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAroundCacheAspect.java @@ -0,0 +1,30 @@ +package com.baeldung.joinpoint; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +@Aspect +@Component +public class JoinPointAroundCacheAspect { + + public final static Map CACHE = new HashMap<>(); + + @Pointcut("execution(* com.baeldung.joinpoint.ArticleService.getArticleList(..))") + public void articleListPointcut() { } + + @Around("articleListPointcut()") + public Object aroundAdviceCache(ProceedingJoinPoint pjp) throws Throwable { + Object articles = CACHE.get(pjp.getArgs()); + if (articles == null) { + articles = pjp.proceed(pjp.getArgs()); + CACHE.put(pjp.getArgs(), articles); + } + return articles; + } +} diff --git a/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAroundExceptionAspect.java b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAroundExceptionAspect.java new file mode 100644 index 0000000000..8d15de150d --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointAroundExceptionAspect.java @@ -0,0 +1,30 @@ +package com.baeldung.joinpoint; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; + +import java.util.logging.Logger; + +@Aspect +@Component +public class JoinPointAroundExceptionAspect { + + private static final java.util.logging.Logger log = Logger.getLogger(JoinPointAroundExceptionAspect.class.getName()); + + @Pointcut("execution(* com.baeldung.joinpoint.ArticleService.getArticleList(..))") + public void articleListPointcut() { } + + @Around("articleListPointcut()") + public Object aroundAdviceException(ProceedingJoinPoint pjp) throws Throwable { + try { + return pjp.proceed(pjp.getArgs()); + } catch (Throwable e) { + log.severe(e.getMessage()); + log.info("Retrying operation"); + return pjp.proceed(pjp.getArgs()); + } + } +} diff --git a/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointBeforeAspect.java b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointBeforeAspect.java new file mode 100644 index 0000000000..4485363ff9 --- /dev/null +++ b/spring-aop/src/main/java/com/baeldung/joinpoint/JoinPointBeforeAspect.java @@ -0,0 +1,32 @@ +package com.baeldung.joinpoint; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.logging.Logger; + +import static java.lang.String.format; + +@Aspect +@Component +public class JoinPointBeforeAspect { + + private static final Logger log = Logger.getLogger(JoinPointBeforeAspect.class.getName()); + + @Pointcut("execution(* com.baeldung.joinpoint.ArticleService.getArticleList(..))") + public void articleListPointcut() { } + + @Before("articleListPointcut()") + public void beforeAdvice(JoinPoint joinPoint) { + log.info( + format("Method %s executed with %s arguments", + joinPoint.getStaticPart().getSignature(), + Arrays.toString(joinPoint.getArgs()) + ) + ); + } +} diff --git a/spring-aop/src/test/java/com/baeldung/joinpoint/ArticleServiceIntegrationTest.java b/spring-aop/src/test/java/com/baeldung/joinpoint/ArticleServiceIntegrationTest.java new file mode 100644 index 0000000000..a67b843262 --- /dev/null +++ b/spring-aop/src/test/java/com/baeldung/joinpoint/ArticleServiceIntegrationTest.java @@ -0,0 +1,39 @@ +package com.baeldung.joinpoint; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.List; + +import static org.junit.Assert.assertFalse; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest +public class ArticleServiceIntegrationTest { + + @Autowired + private ArticleService articleService; + + @Test + public void shouldGetNotEmptyArticleList() { + List articleList = articleService.getArticleList(); + + assertFalse(articleList.isEmpty()); + } + + @Test + public void shouldGetNotEmptyArticleListWithStartsWithFilter() { + List articleList = articleService.getArticleList("Article"); + + assertFalse(articleList.isEmpty()); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldThrowExceptionIfStartsWithFilterIsBlank() { + articleService.getArticleList(" "); + } + +} diff --git a/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAfterThrowingAspectIntegrationTest.java b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAfterThrowingAspectIntegrationTest.java new file mode 100644 index 0000000000..cdef76ac0d --- /dev/null +++ b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAfterThrowingAspectIntegrationTest.java @@ -0,0 +1,60 @@ +package com.baeldung.joinpoint; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Handler; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest +@EnableAspectJAutoProxy +public class JoinPointAfterThrowingAspectIntegrationTest { + + private final List messages = new ArrayList<>(); + + @Before + public void setUp() { + Handler logEventHandler = new Handler() { + @Override + public void publish(LogRecord record) { + messages.add(record.getLevel().getName() + " " + record.getMessage()); + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }; + + Logger logger = Logger.getLogger(JoinPointAfterThrowingAspect.class.getName()); + logger.addHandler(logEventHandler); + } + + @Autowired + private ArticleService articleService; + + @Test(expected = IllegalArgumentException.class) + public void shouldLogMethodSignatureBeforeExecution() { + articleService.getArticleList(" "); + + assertThat(messages, hasSize(1)); + assertTrue(messages.contains("SEVERE startsWithFilter can't be blank")); + } + +} diff --git a/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAroundCacheAspectIntegrationTest.java b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAroundCacheAspectIntegrationTest.java new file mode 100644 index 0000000000..4bd8f2ad8e --- /dev/null +++ b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAroundCacheAspectIntegrationTest.java @@ -0,0 +1,35 @@ +package com.baeldung.joinpoint; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest +@EnableAspectJAutoProxy +public class JoinPointAroundCacheAspectIntegrationTest { + + @Autowired + private ArticleService articleService; + + @Test + public void shouldPopulateCache() { + assertTrue(JoinPointAroundCacheAspect.CACHE.isEmpty()); + + List articles = articleService.getArticleList(); + + assertFalse(JoinPointAroundCacheAspect.CACHE.isEmpty()); + assertEquals(JoinPointAroundCacheAspect.CACHE.size(), 1); + assertEquals(JoinPointAroundCacheAspect.CACHE.values().iterator().next(), articles); + } + +} diff --git a/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAroundExceptionAspectIntegrationTest.java b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAroundExceptionAspectIntegrationTest.java new file mode 100644 index 0000000000..dbdda30c15 --- /dev/null +++ b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointAroundExceptionAspectIntegrationTest.java @@ -0,0 +1,60 @@ +package com.baeldung.joinpoint; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Handler; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest +@EnableAspectJAutoProxy +public class JoinPointAroundExceptionAspectIntegrationTest { + + private final List messages = new ArrayList<>(); + + @Before + public void setUp() { + Handler logEventHandler = new Handler() { + @Override + public void publish(LogRecord record) { + messages.add(record.getLevel().getName() + " " + record.getMessage()); + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }; + + Logger logger = Logger.getLogger(JoinPointAroundExceptionAspect.class.getName()); + logger.addHandler(logEventHandler); + } + + @Autowired + private ArticleService articleService; + + @Test(expected = IllegalArgumentException.class) + public void shouldLogMethodSignatureBeforeExecution() { + articleService.getArticleList(" "); + + assertThat(messages, hasSize(1)); + assertTrue(messages.contains("INFO Retrying operation")); + } + +} diff --git a/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointBeforeAspectIntegrationTest.java b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointBeforeAspectIntegrationTest.java new file mode 100644 index 0000000000..631852d57f --- /dev/null +++ b/spring-aop/src/test/java/com/baeldung/joinpoint/JoinPointBeforeAspectIntegrationTest.java @@ -0,0 +1,60 @@ +package com.baeldung.joinpoint; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Handler; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest +@EnableAspectJAutoProxy +public class JoinPointBeforeAspectIntegrationTest { + + private final List messages = new ArrayList<>(); + + @Before + public void setUp() { + Handler logEventHandler = new Handler() { + @Override + public void publish(LogRecord record) { + messages.add(record.getLevel().getName() + " " + record.getMessage()); + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }; + + Logger logger = Logger.getLogger(JoinPointBeforeAspect.class.getName()); + logger.addHandler(logEventHandler); + } + + @Autowired + private ArticleService articleService; + + @Test + public void shouldLogMethodSignatureBeforeExecution() { + articleService.getArticleList(); + + assertThat(messages, hasSize(1)); + assertTrue(messages.contains("INFO Method List com.baeldung.joinpoint.ArticleService.getArticleList() executed with [] arguments")); + } + +} diff --git a/spring-boot-modules/spring-boot-keycloak/pom.xml b/spring-boot-modules/spring-boot-keycloak/pom.xml index 505d486509..b80dbfa191 100644 --- a/spring-boot-modules/spring-boot-keycloak/pom.xml +++ b/spring-boot-modules/spring-boot-keycloak/pom.xml @@ -77,8 +77,6 @@ 13.0.1 - - 2.5.3 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-connectors-heroku/pom.xml b/spring-cloud/spring-cloud-connectors-heroku/pom.xml index e02da23f6c..24f9de1fc3 100644 --- a/spring-cloud/spring-cloud-connectors-heroku/pom.xml +++ b/spring-cloud/spring-cloud-connectors-heroku/pom.xml @@ -16,9 +16,10 @@ - + org.springframework.boot spring-boot-starter-cloud-connectors + ${spring-boot-starter-cloud-connectors.version} org.springframework.boot @@ -56,9 +57,9 @@ - 2.2.6.RELEASE + 2.2.6.RELEASE Hoxton.SR4 42.2.10 - \ No newline at end of file + diff --git a/spring-cloud/spring-cloud-kubernetes/kubernetes-guide/travel-agency-service/pom.xml b/spring-cloud/spring-cloud-kubernetes/kubernetes-guide/travel-agency-service/pom.xml index c6c6de94c3..ba5ba93682 100644 --- a/spring-cloud/spring-cloud-kubernetes/kubernetes-guide/travel-agency-service/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/kubernetes-guide/travel-agency-service/pom.xml @@ -62,8 +62,4 @@ - - 1.2.3 - - \ No newline at end of file diff --git a/spring-jersey/pom.xml b/spring-jersey/pom.xml index 08c19f1d3b..64a34074bb 100644 --- a/spring-jersey/pom.xml +++ b/spring-jersey/pom.xml @@ -212,6 +212,7 @@ 2.29.1 + 2.11.1 1.6.1 4.4.9 4.5.5 diff --git a/spring-security-modules/spring-5-security-oauth/pom.xml b/spring-security-modules/spring-5-security-oauth/pom.xml index 03e1880431..194ace35b0 100644 --- a/spring-security-modules/spring-5-security-oauth/pom.xml +++ b/spring-security-modules/spring-5-security-oauth/pom.xml @@ -68,6 +68,8 @@ + + 2.5.2 com.baeldung.oauth2.SpringOAuthApplication diff --git a/spring-security-modules/spring-security-web-sockets/README.md b/spring-security-modules/spring-security-web-sockets/README.md index 76717e2fe6..34e06fa832 100644 --- a/spring-security-modules/spring-security-web-sockets/README.md +++ b/spring-security-modules/spring-security-web-sockets/README.md @@ -10,8 +10,8 @@ This module contains articles about WebSockets with Spring Security ### Running This Project: -To build the project, run the command: mvn clean install. This will build a war file in the target folder that you can deploye on a server like Tomcat. +To build the project, run the command: `mvn clean install`. This will build a war file in the target folder that you can deploy on a server like Tomcat. -Alternatively, run the project from an IDE. +Alternatively, run the project from an IDE, with the maven goal `org.codehaus.cargo:cargo-maven2-plugin:run` To login, use credentials from the data.sql file in src/main/resource, eg: user/password. diff --git a/spring-security-modules/spring-security-web-sockets/pom.xml b/spring-security-modules/spring-security-web-sockets/pom.xml index b1536e88ea..802c894612 100644 --- a/spring-security-modules/spring-security-web-sockets/pom.xml +++ b/spring-security-modules/spring-security-web-sockets/pom.xml @@ -103,7 +103,7 @@ ch.qos.logback logback-classic - ${logback-classic.version} + ${logback.version} @@ -155,11 +155,14 @@ spring-security-web-sockets - org.apache.tomcat.maven - tomcat7-maven-plugin - 2.2 + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} - /spring-security-mvc-socket + + tomcat9x + embedded + @@ -177,8 +180,8 @@ 5.2.10.Final 1.11.3.RELEASE - 1.2.3 1.5.10.RELEASE + 1.7.6 \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java b/spring-web-modules/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpManualTest.java similarity index 66% rename from spring-web-modules/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java rename to spring-web-modules/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpManualTest.java index 0aa23842b1..99a76099b2 100644 --- a/spring-web-modules/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java +++ b/spring-web-modules/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpManualTest.java @@ -10,13 +10,18 @@ import com.maxmind.geoip2.DatabaseReader; import com.maxmind.geoip2.exception.GeoIp2Exception; import com.maxmind.geoip2.model.CityResponse; -public class GeoIpIntegrationTest { +public class GeoIpManualTest { @Test public void givenIP_whenFetchingCity_thenReturnsCityData() throws IOException, GeoIp2Exception { ClassLoader classLoader = getClass().getClassLoader(); - File database = new File(classLoader.getResource("GeoLite2-City.mmdb").getFile()); + /** + * Download the db file as shown in the article https://www.baeldung.com/geolocation-by-ip-with-maxmind, + * then replace the "your-path-to-db-file" string in the test with the file path before running the test + * HINT : Copy the downloaded file at spring-web-modules/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb + * **/ + File database = new File("your-path-to-db-file"); DatabaseReader dbReader = new DatabaseReader.Builder(database).build(); InetAddress ipAddress = InetAddress.getByName("google.com"); diff --git a/spring-web-modules/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb b/spring-web-modules/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb deleted file mode 100644 index 6de839a7ed..0000000000 Binary files a/spring-web-modules/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb and /dev/null differ diff --git a/spring-websockets/README.md b/spring-websockets/README.md index 9cc84f0fda..7d69c21b78 100644 --- a/spring-websockets/README.md +++ b/spring-websockets/README.md @@ -6,3 +6,4 @@ This module contains articles about Spring WebSockets. - [Intro to WebSockets with Spring](https://www.baeldung.com/websockets-spring) - [A Quick Example of Spring Websockets’ @SendToUser Annotation](https://www.baeldung.com/spring-websockets-sendtouser) - [Scheduled WebSocket Push with Spring Boot](https://www.baeldung.com/spring-boot-scheduled-websocket) +- [Test WebSocket APIs With Postman](https://www.baeldung.com/postman-websocket-apis) diff --git a/spring-websockets/src/main/java/com/baeldung/rawwebsocket/ServerWebSocketConfig.java b/spring-websockets/src/main/java/com/baeldung/rawwebsocket/ServerWebSocketConfig.java new file mode 100644 index 0000000000..5218140d2c --- /dev/null +++ b/spring-websockets/src/main/java/com/baeldung/rawwebsocket/ServerWebSocketConfig.java @@ -0,0 +1,23 @@ +package com.baeldung.rawwebsocket; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; + +@Configuration +@EnableWebSocket +public class ServerWebSocketConfig implements WebSocketConfigurer { + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(webSocketHandler(), "/websocket"); + } + + @Bean + public WebSocketHandler webSocketHandler() { + return new ServerWebSocketHandler(); + } +} diff --git a/spring-websockets/src/main/java/com/baeldung/rawwebsocket/ServerWebSocketHandler.java b/spring-websockets/src/main/java/com/baeldung/rawwebsocket/ServerWebSocketHandler.java new file mode 100644 index 0000000000..ed1ac8edc3 --- /dev/null +++ b/spring-websockets/src/main/java/com/baeldung/rawwebsocket/ServerWebSocketHandler.java @@ -0,0 +1,72 @@ +package com.baeldung.rawwebsocket; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.web.socket.CloseStatus; +import org.springframework.web.socket.SubProtocolCapable; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.TextWebSocketHandler; +import org.springframework.web.util.HtmlUtils; + +import java.io.IOException; +import java.time.LocalTime; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +public class ServerWebSocketHandler extends TextWebSocketHandler implements SubProtocolCapable { + + private static final Logger logger = LoggerFactory.getLogger(ServerWebSocketHandler.class); + + private final Set sessions = new CopyOnWriteArraySet<>(); + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + logger.info("Server connection opened"); + sessions.add(session); + + TextMessage message = new TextMessage("one-time message from server"); + logger.info("Server sends: {}", message); + session.sendMessage(message); + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { + logger.info("Server connection closed: {}", status); + sessions.remove(session); + } + + @Scheduled(fixedRate = 10000) + void sendPeriodicMessages() throws IOException { + for (WebSocketSession session : sessions) { + if (session.isOpen()) { + String broadcast = "server periodic message " + LocalTime.now(); + logger.info("Server sends: {}", broadcast); + session.sendMessage(new TextMessage(broadcast)); + } + } + } + + @Override + public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { + String request = message.getPayload(); + logger.info("Server received: {}", request); + + String response = String.format("response from server to '%s'", HtmlUtils.htmlEscape(request)); + logger.info("Server sends: {}", response); + session.sendMessage(new TextMessage(response)); + } + + @Override + public void handleTransportError(WebSocketSession session, Throwable exception) { + logger.info("Server transport error: {}", exception.getMessage()); + } + + @Override + public List getSubProtocols() { + return Collections.singletonList("subprotocol.demo.websocket"); + } +} diff --git a/vertx-and-rxjava/pom.xml b/vertx-and-rxjava/pom.xml index fb04ba784c..1793cff1e7 100644 --- a/vertx-and-rxjava/pom.xml +++ b/vertx-and-rxjava/pom.xml @@ -47,7 +47,6 @@ 3.5.0.Beta1 - 1.2.3 \ No newline at end of file diff --git a/vraptor/pom.xml b/vraptor/pom.xml index ab78c0d97a..fad17e7aae 100644 --- a/vraptor/pom.xml +++ b/vraptor/pom.xml @@ -68,7 +68,7 @@ org.slf4j slf4j-log4j12 - ${slf4j-log4j12.version} + ${org.slf4j.version} br.com.caelum.vraptor @@ -117,7 +117,6 @@ 2.1.2.Final 2.2 5.1.1.Final - 1.7.5 4.1.0-RC3 4.0.4 8.0.8-dmr
This is the tutorial to convert html to pdf.