Merge branch 'eugenp:master' into master

This commit is contained in:
rvsathe 2021-09-17 08:42:27 +05:30 committed by GitHub
commit d799c1cd85
95 changed files with 2036 additions and 317 deletions

View File

@ -133,6 +133,11 @@
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.jayway.awaitility</groupId>
<artifactId>awaitility</artifactId>
@ -196,7 +201,6 @@
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<avro.version>1.8.2</avro.version>
<slf4j.version>1.7.25</slf4j.version>
<beam.version>2.19.0</beam.version>
<assertj.version>3.9.0</assertj.version>
<bval.version>1.1.2</bval.version>

View File

@ -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);

View File

@ -29,7 +29,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${org.slf4j.slf4j-simple.version}</version>
<version>${org.slf4j.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
@ -61,7 +61,6 @@
<properties>
<thrift.version>0.10.0</thrift.version>
<maven-thrift.version>0.1.11</maven-thrift.version>
<org.slf4j.slf4j-simple.version>1.7.12</org.slf4j.slf4j-simple.version>
<build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
</properties>

View File

@ -166,7 +166,6 @@
<hsqldb.version>2.4.0</hsqldb.version>
<spock-core.version>1.1-groovy-2.4</spock-core.version>
<groovy-wslite.version>1.1.3</groovy-wslite.version>
<logback.version>1.2.3</logback.version>
<groovy.version>2.5.7</groovy.version>
<assembly.plugin.version>3.1.0</assembly.plugin.version>
<compiler.plugin.version>3.8.0</compiler.plugin.version>

View File

@ -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)

View File

@ -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)

View File

@ -26,10 +26,50 @@
<version>${assertj-core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
</dependency>
</dependencies>
<properties>
<assertj-core.version>3.10.0</assertj-core.version>
<jmh.version>1.33</jmh.version>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.baeldung.copyarraymethodsperformance.BenchmarkRunner</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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<ProcessHandle> 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<ProcessHandle> children = ProcessHandle.current()
.children();
children.filter(ProcessHandle::isAlive)
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info()
.command()));
Stream<ProcessHandle> 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<ProcessHandle> onProcessExit = processHandle.onExit();
onProcessExit.get();
log.info("Alive: " + processHandle.isAlive());
onProcessExit.thenAccept(ph -> {
log.info("PID: {} has stopped", ph.pid());
});
}
}

View File

@ -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<ProcessHandle> 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<ProcessHandle> children = ProcessHandle.current()
.children();
children.filter(ProcessHandle::isAlive)
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info()
.command()));
Stream<ProcessHandle> 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<ProcessHandle> onProcessExit = processHandle.onExit();
onProcessExit.get();
assertEquals(false, processHandle.isAlive());
onProcessExit.thenAccept(ph -> {
log.info("PID: {} has stopped", ph.pid());
});
}
}

View File

@ -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)

View File

@ -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);
}
}

View File

@ -39,12 +39,12 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<version>${org.slf4j.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.datavec/datavec-api -->
<dependency>
@ -62,7 +62,6 @@
<properties>
<dl4j.version>0.9.1</dl4j.version> <!-- Latest non beta version -->
<httpclient.version>4.3.5</httpclient.version>
<slf4j.version>1.7.5</slf4j.version>
</properties>
</project>

View File

@ -99,7 +99,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
@ -204,8 +204,6 @@
<spring.boot.version>1.5.6.RELEASE</spring.boot.version>
<mockito.version>2.21.0</mockito.version>
<jsonpath.version>2.4.0</jsonpath.version>
<logback.version>1.2.3</logback.version>
<slf4j.version>1.7.25</slf4j.version>
<spring-boot-maven-plugin.version>2.0.4.RELEASE</spring-boot-maven-plugin.version>
<compiler.plugin.version>3.1</compiler.plugin.version>
</properties>

View File

@ -24,7 +24,7 @@
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson-datatype.version}</version>
<version>${jackson.version}</version>
</dependency>
<!-- CSV -->
<dependency>
@ -52,7 +52,6 @@
<properties>
<assertj.version>3.11.0</assertj.version>
<jackson-datatype.version>2.9.8</jackson-datatype.version>
</properties>
</project>

View File

@ -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<SubTypeConstructorStructure.Vehicle> vehicles = new ArrayList<>();
List<Vehicle> 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));
}
}

View File

@ -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);

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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) ? "<null>" : this.name));
sb.append(((this.name == null)?"<null>":this.name));
sb.append(',');
sb.append("area");
sb.append('=');
sb.append(((this.area == null) ? "<null>" : this.area));
sb.append(((this.area == null)?"<null>":this.area));
sb.append(',');
sb.append("author");
sb.append('=');
sb.append(((this.author == null) ? "<null>" : this.author));
sb.append(((this.author == null)?"<null>":this.author));
sb.append(',');
sb.append("id");
sb.append('=');
sb.append(((this.id == null) ? "<null>" : this.id));
sb.append(((this.id == null)?"<null>":this.id));
sb.append(',');
sb.append("salary");
sb.append('=');
sb.append(((this.salary == null) ? "<null>" : this.salary));
sb.append(((this.salary == null)?"<null>":this.salary));
sb.append(',');
sb.append("topics");
sb.append('=');
sb.append(((this.topics == null) ? "<null>" : this.topics));
sb.append(((this.topics == null)?"<null>":this.topics));
sb.append(',');
sb.append("additionalProperties");
sb.append('=');
sb.append(((this.additionalProperties == null) ? "<null>" : this.additionalProperties));
sb.append(((this.additionalProperties == null)?"<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))));
}
}

View File

@ -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<String, Object> additionalProperties = new HashMap<String, Object>();
@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<String, Object> 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)?"<null>":this.city));
sb.append(',');
sb.append("country");
sb.append('=');
sb.append(((this.country == null)?"<null>":this.country));
sb.append(',');
sb.append("additionalProperties");
sb.append('=');
sb.append(((this.additionalProperties == null)?"<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))));
}
}

View File

@ -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<String> topics = new ArrayList<String>();
@JsonProperty("address")
private Address address;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@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<String> getTopics() {
return topics;
}
@JsonProperty("topics")
public void setTopics(List<String> topics) {
this.topics = topics;
}
public Input withTopics(List<String> 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<String, Object> 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)?"<null>":this.name));
sb.append(',');
sb.append("area");
sb.append('=');
sb.append(((this.area == null)?"<null>":this.area));
sb.append(',');
sb.append("author");
sb.append('=');
sb.append(((this.author == null)?"<null>":this.author));
sb.append(',');
sb.append("id");
sb.append('=');
sb.append(((this.id == null)?"<null>":this.id));
sb.append(',');
sb.append("topics");
sb.append('=');
sb.append(((this.topics == null)?"<null>":this.topics));
sb.append(',');
sb.append("address");
sb.append('=');
sb.append(((this.address == null)?"<null>":this.address));
sb.append(',');
sb.append("additionalProperties");
sb.append('=');
sb.append(((this.additionalProperties == null)?"<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))));
}
}

View File

@ -0,0 +1,16 @@
{
"name": "Baeldung",
"area": "tech blogs",
"author": "Eugen",
"id": 32134,
"topics": [
"java",
"kotlin",
"cs",
"linux"
],
"address": {
"city": "Bucharest",
"country": "Romania"
}
}

View File

@ -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())));
}

View File

@ -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<String> topics = new ArrayList<String>();
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@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<String> getTopics() {
return topics;
}
@JsonProperty("topics")
public void setTopics(List<String> topics) {
this.topics = topics;
}
public SamplePojo withTopics(List<String> topics) {
this.topics = topics;
return this;
}
@JsonAnyGetter
public Map<String, Object> 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)?"<null>":this.name));
sb.append(',');
sb.append("area");
sb.append('=');
sb.append(((this.area == null)?"<null>":this.area));
sb.append(',');
sb.append("author");
sb.append('=');
sb.append(((this.author == null)?"<null>":this.author));
sb.append(',');
sb.append("id");
sb.append('=');
sb.append(((this.id == null)?"<null>":this.id));
sb.append(',');
sb.append("salary");
sb.append('=');
sb.append(((this.salary == null)?"<null>":this.salary));
sb.append(',');
sb.append("topics");
sb.append('=');
sb.append(((this.topics == null)?"<null>":this.topics));
sb.append(',');
sb.append("additionalProperties");
sb.append('=');
sb.append(((this.additionalProperties == null)?"<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))));
}
}

View File

@ -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)

View File

@ -104,12 +104,12 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>com.univocity</groupId>
@ -161,7 +161,6 @@
<suanshu.version>4.0.0</suanshu.version>
<derive4j.version>1.1.0</derive4j.version>
<assertj.version>3.6.2</assertj.version>
<slf4j.version>1.7.25</slf4j.version>
<awaitility.version>3.0.0</awaitility.version>
<univocity.version>2.8.4</univocity.version>
<guava.version>29.0-jre</guava.version>

View File

@ -108,7 +108,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.storm</groupId>
@ -173,7 +173,6 @@
<hazelcast.version>3.8.4</hazelcast.version>
<org.apache.crunch.crunch-core.version>0.15.0</org.apache.crunch.crunch-core.version>
<org.apache.hadoop.hadoop-client>2.2.0</org.apache.hadoop.hadoop-client>
<slf4j.version>1.7.25</slf4j.version>
<jmapper.version>1.6.0.1</jmapper.version>
</properties>

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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<File> 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<File> filesToAdd = Arrays.asList(firstFile, secondFile);
ZipFile zipFile = new ZipFile("compressed.zip", "password".toCharArray());
zipFile.addFiles(filesToAdd, zipParameters);
zipFile.close();
}
}

View File

@ -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();
}
}

View File

@ -69,7 +69,6 @@
</dependencies>
<properties>
<logback.version>1.2.3</logback.version>
<logback.contrib.version>0.1.5</logback.contrib.version>
<docx4j.version>3.3.5</docx4j.version>
<javax.mail.version>1.4.7</javax.mail.version>

View File

@ -1,3 +1,3 @@
### Relevant Articles:
- [Understanding the "relativePath" Tag - Maven Parent POM Resolution At A Glance](https://www.baeldung.com/maven-relativepath)
- [Understanding Mavens “relativePath” Tag for a Parent POM](https://www.baeldung.com/maven-relativepath)

View File

@ -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">
<modelVersion>4.0.0</modelVersion>
<artifactId>project-b</artifactId>
<artifactId>module1</artifactId>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>project-a</artifactId>
<version>1.0-SNAPSHOT</version>
<groupId>com.baeldung.maven-parent-pom-resolution</groupId>
<artifactId>aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<!-- The parent pom is resolved to project a's pom.xml -->
</parent>
<packaging>pom</packaging>

View File

@ -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">
<modelVersion>4.0.0</modelVersion>
<artifactId>project-d</artifactId>
<artifactId>module3</artifactId>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>project-a</artifactId>
<version>1.0-SNAPSHOT</version>
<groupId>com.baeldung.maven-parent-pom-resolution</groupId>
<artifactId>aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<!-- removing relativePath won't work even if project-a is the aggregator project -->
<!-- it only works in IntelliJ IDEA when project-a is registered as a Maven Project -->
<relativePath>../../pom.xml</relativePath>

View File

@ -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">
<modelVersion>4.0.0</modelVersion>
<artifactId>project-c</artifactId>
<artifactId>module2</artifactId>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>project-b</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../project-b/pom.xml</relativePath>
<groupId>com.baeldung.maven-parent-pom-resolution</groupId>
<artifactId>module1</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../module1/pom.xml</relativePath>
<!-- The parent pom is resolved to project a's pom.xml -->
</parent>
<packaging>pom</packaging>
<modules>
<module>project-d</module>
<module>module3</module>
</modules>
</project>

View File

@ -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">
<modelVersion>4.0.0</modelVersion>
<artifactId>project-a</artifactId>
<groupId>com.baeldung.maven-parent-pom-resolution</groupId>
<artifactId>aggregator</artifactId>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>maven-parent-pom-resolution</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.0.0-SNAPSHOT</version>
<!-- The parent pom is resolved to ../pom.xml -->
</parent>
<packaging>pom</packaging>
<modules>
<module>project-b</module>
<module>project-c</module>
<module>module1</module>
<module>module2</module>
</modules>
</project>

View File

@ -5,11 +5,11 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>maven-parent-pom-resolution</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>project-a</module>
<module>aggregator</module>
</modules>
<!-- to detect the POM hierarchy, just type "mvn dependency:display-ancestors" -->

View File

@ -61,7 +61,7 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${lombok.version}</version>
<version>${logback.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
@ -145,7 +145,6 @@
<micronaut.version>1.0.0.RC2</micronaut.version>
<jdk.version>1.8</jdk.version>
<annotation.api.version>1.3.2</annotation.api.version>
<lombok.version>1.2.3</lombok.version>
<reactor.version>3.1.6.RELEASE</reactor.version>
<compiler.plugin.version>3.7.0</compiler.plugin.version>
<shade.plugin.version>3.1.0</shade.plugin.version>

View File

@ -81,7 +81,7 @@
<rest-assured.version>3.3.0</rest-assured.version>
<!-- plugins -->
<thin.version>1.0.22.RELEASE</thin.version>
<spring-boot.version>2.5.1</spring-boot.version>
<spring-boot.version>2.5.4</spring-boot.version>
<aspectjweaver.version>1.9.1</aspectjweaver.version>
<!-- this property can be removed once we update Mockito version in the main pom.xml -->
<mockito.version>3.4.0</mockito.version>

View File

@ -71,6 +71,26 @@
<artifactId>flying-saucer-pdf</artifactId>
<version>${flying-saucer-pdf.version}</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-openpdf</artifactId>
<version>${flying-saucer-pdf-openpdf.version}</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${jsoup.version}</version>
</dependency>
<dependency>
<groupId>com.openhtmltopdf</groupId>
<artifactId>openhtmltopdf-core</artifactId>
<version>${open-html-pdf-core.version}</version>
</dependency>
<dependency>
<groupId>com.openhtmltopdf</groupId>
<artifactId>openhtmltopdf-pdfbox</artifactId>
<version>${open-html-pdfbox.version}</version>
</dependency>
</dependencies>
<build>
@ -93,6 +113,10 @@
<poi-ooxml.version>3.15</poi-ooxml.version>
<thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
<flying-saucer-pdf.version>9.1.20</flying-saucer-pdf.version>
<open-html-pdfbox.version>1.0.6</open-html-pdfbox.version>
<open-html-pdf-core.version>1.0.6</open-html-pdf-core.version>
<flying-saucer-pdf-openpdf.version>9.1.22</flying-saucer-pdf-openpdf.version>
<jsoup.version>1.14.2</jsoup.version>
</properties>
</project>

View File

@ -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) {
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}

Binary file not shown.

View File

@ -0,0 +1,26 @@
<html>
<head>
<style>
.center_div {
border: 1px solid gray;
margin-left: auto;
margin-right: auto;
width: 90%;
background-color: #d0f0f6;
text-align: left;
padding: 8px;
}
</style>
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="center_div">
<h1>Hello Baeldung!</h1>
<img src="Java_logo.png">
<div class="myclass">
<p>This is the tutorial to convert html to pdf.</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,6 @@
.myclass{
font-family: Helvetica, sans-serif;
font-size:25;
font-weight: normal;
color: blue;
}

View File

@ -77,7 +77,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<version>${org.slf4j.version}</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
@ -174,12 +174,10 @@
<javassist.version>3.27.0-GA</javassist.version>
<jaxb.version>2.3.1</jaxb.version>
<log4jdbc.version>2.0.0</log4jdbc.version>
<logback.version>1.2.3</logback.version>
<maven-jar-plugin.version>3.0.2</maven-jar-plugin.version>
<maven.compiler.version>3.8.1</maven.compiler.version>
<maven.version>3.8.1</maven.version>
<mysql.version>8.0.19</mysql.version>
<slf4j.version>1.7.30</slf4j.version>
<spring-boot.version>2.1.3.RELEASE</spring-boot.version>
</properties>

View File

@ -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)

View File

@ -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<MerchandiseEntity> 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());
}
}

View File

@ -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)

View File

@ -1410,7 +1410,7 @@
<jstl-api.version>1.2</jstl-api.version>
<javax.servlet.jsp-api.version>2.3.1</javax.servlet.jsp-api.version>
<jstl.version>1.2</jstl.version>
<jackson.version>2.11.1</jackson.version>
<jackson.version>2.12.4</jackson.version>
<commons-fileupload.version>1.4</commons-fileupload.version>
<junit-platform.version>1.2.0</junit-platform.version>
<junit-jupiter.version>5.2.0</junit-jupiter.version>

View File

@ -99,7 +99,7 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-classic.version}</version>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>io.restx</groupId>
@ -149,7 +149,6 @@
<properties>
<restx.version>0.35-rc4</restx.version>
<logback-classic.version>1.2.3</logback-classic.version>
</properties>
</project>

View File

@ -99,7 +99,6 @@
<properties>
<spf4j.version>8.9.0</spf4j.version>
<org.slf4j.version>1.7.21</org.slf4j.version>
<compiler.plugin.version>3.8.0</compiler.plugin.version>
<dependency.plugin.version>3.1.1</dependency.plugin.version>
</properties>

View File

@ -105,7 +105,6 @@
<properties>
<spf4j.version>8.9.0</spf4j.version>
<org.slf4j.version>1.7.21</org.slf4j.version>
<compiler.plugin.version>3.8.0</compiler.plugin.version>
<dependency.plugin.version>3.1.1</dependency.plugin.version>
</properties>

View File

@ -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)

View File

@ -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<HttpStatus> uploadPdf(@RequestParam("file") final MultipartFile multipartFile) {
return uploadService.uploadPdf(multipartFile.getResource());
}
@PostMapping(path = "/upload/multipart")
@ResponseBody
public Mono<HttpStatus> uploadMultipart(@RequestParam("file") final MultipartFile multipartFile) {
return uploadService.uploadMultipart(multipartFile);
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.reactive.exception;
public class ServiceException extends RuntimeException{
public ServiceException(String message) {
super(message);
}
}

View File

@ -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<HttpStatus> uploadPdf(final Resource resource) {
final URI url = UriComponentsBuilder.fromHttpUrl(EXTERNAL_UPLOAD_URL).build().toUri();
Mono<HttpStatus> 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<HttpStatus> 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<HttpStatus> 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;
}
}

View File

@ -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<HttpStatus> 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<HttpStatus> result = tested.uploadMultipart(multipartFile);
final HttpStatus status = result.block();
assertThat(status).isEqualTo(HttpStatus.OK);
}
}

View File

@ -65,8 +65,4 @@
</plugins>
</build>
<properties>
<spring-boot.version>2.3.3.RELEASE</spring-boot.version>
</properties>
</project>

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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<String> getArticleList() {
return Arrays.asList(
"Article 1",
"Article 2"
);
}
public List<String> 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());
}
}

View File

@ -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());
}
}

View File

@ -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<Object, Object> 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;
}
}

View File

@ -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());
}
}
}

View File

@ -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())
)
);
}
}

View File

@ -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<String> articleList = articleService.getArticleList();
assertFalse(articleList.isEmpty());
}
@Test
public void shouldGetNotEmptyArticleListWithStartsWithFilter() {
List<String> articleList = articleService.getArticleList("Article");
assertFalse(articleList.isEmpty());
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfStartsWithFilterIsBlank() {
articleService.getArticleList(" ");
}
}

View File

@ -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<String> 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"));
}
}

View File

@ -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<String> articles = articleService.getArticleList();
assertFalse(JoinPointAroundCacheAspect.CACHE.isEmpty());
assertEquals(JoinPointAroundCacheAspect.CACHE.size(), 1);
assertEquals(JoinPointAroundCacheAspect.CACHE.values().iterator().next(), articles);
}
}

View File

@ -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<String> 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"));
}
}

View File

@ -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<String> 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"));
}
}

View File

@ -77,8 +77,6 @@
<properties>
<keycloak-adapter-bom.version>13.0.1</keycloak-adapter-bom.version>
<!-- explicit version declaration to be removed when parent-boot-2 is upgraded to 2.5.3 or above -->
<spring-boot.version>2.5.3</spring-boot.version>
</properties>
</project>

View File

@ -16,9 +16,10 @@
</parent>
<dependencies>
<dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cloud-connectors</artifactId>
<version>${spring-boot-starter-cloud-connectors.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@ -56,9 +57,9 @@
</dependencyManagement>
<properties>
<spring-boot.version>2.2.6.RELEASE</spring-boot.version>
<spring-boot-starter-cloud-connectors.version>2.2.6.RELEASE</spring-boot-starter-cloud-connectors.version>
<spring-cloud-dependencies.version>Hoxton.SR4</spring-cloud-dependencies.version>
<postgresql.version>42.2.10</postgresql.version>
</properties>
</project>
</project>

View File

@ -62,8 +62,4 @@
</plugins>
</build>
<properties>
<logback.version>1.2.3</logback.version>
</properties>
</project>

View File

@ -212,6 +212,7 @@
<properties>
<jersey.version>2.29.1</jersey.version>
<jackson.version>2.11.1</jackson.version>
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
<httpcore.version>4.4.9</httpcore.version>
<httpclient.version>4.5.5</httpclient.version>

View File

@ -68,6 +68,8 @@
</dependencies>
<properties>
<!-- Remove this explicit override once more recent version of spring-security-oauth2-autoconfigure is available -->
<spring-boot.version>2.5.2</spring-boot.version>
<start-class>com.baeldung.oauth2.SpringOAuthApplication</start-class>
</properties>

View File

@ -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.

View File

@ -103,7 +103,7 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-classic.version}</version>
<version>${logback.version}</version>
</dependency>
<!-- Servlet -->
<dependency>
@ -155,11 +155,14 @@
<finalName>spring-security-web-sockets</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>${cargo-maven2-plugin.version}</version>
<configuration>
<path>/spring-security-mvc-socket</path>
<container>
<containerId>tomcat9x</containerId>
<type>embedded</type>
</container>
</configuration>
</plugin>
<plugin>
@ -177,8 +180,8 @@
<properties>
<hibernate-core.version>5.2.10.Final</hibernate-core.version>
<spring-data-jpa.version>1.11.3.RELEASE</spring-data-jpa.version>
<logback-classic.version>1.2.3</logback-classic.version>
<spring-boot-starter-test.version>1.5.10.RELEASE</spring-boot-starter-test.version>
<cargo-maven2-plugin.version>1.7.6</cargo-maven2-plugin.version>
</properties>
</project>

View File

@ -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");

View File

@ -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)

View File

@ -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();
}
}

View File

@ -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<WebSocketSession> 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<String> getSubProtocols() {
return Collections.singletonList("subprotocol.demo.websocket");
}
}

View File

@ -47,7 +47,6 @@
<properties>
<vertx.version>3.5.0.Beta1</vertx.version>
<logback.version>1.2.3</logback.version>
</properties>
</project>

View File

@ -68,7 +68,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-log4j12.version}</version>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>br.com.caelum.vraptor</groupId>
@ -117,7 +117,6 @@
<weld.version>2.1.2.Final</weld.version>
<el.version>2.2</el.version>
<hibernate-validator.version>5.1.1.Final</hibernate-validator.version>
<slf4j-log4j12.version>1.7.5</slf4j-log4j12.version>
<vraptor-freemarker.version>4.1.0-RC3</vraptor-freemarker.version>
<vraptor-hibernate.version>4.0.4</vraptor-hibernate.version>
<mysql-connector.version>8.0.8-dmr</mysql-connector.version>