Merge branch 'eugenp:master' into PR-7145

This commit is contained in:
parthiv39731 2023-10-30 18:02:14 +05:30 committed by GitHub
commit 4fd895c2ec
135 changed files with 1180 additions and 39 deletions

View File

@ -5,6 +5,5 @@ This module contains articles about various Amazon Web Services (AWS) such as EC
### Relevant articles ### Relevant articles
- [Managing EC2 Instances in Java](https://www.baeldung.com/ec2-java) - [Managing EC2 Instances in Java](https://www.baeldung.com/ec2-java)
- [Integration Testing with a Local DynamoDB Instance](https://www.baeldung.com/dynamodb-local-integration-tests)
- [Managing Amazon SQS Queues in Java](https://www.baeldung.com/aws-queues-java) - [Managing Amazon SQS Queues in Java](https://www.baeldung.com/aws-queues-java)
- [Guide to AWS Aurora RDS with Java](https://www.baeldung.com/aws-aurora-rds-java) - [Guide to AWS Aurora RDS with Java](https://www.baeldung.com/aws-aurora-rds-java)

View File

@ -11,5 +11,5 @@ This module contains articles about Java 8 core features
- [Finding Min/Max in an Array with Java](https://www.baeldung.com/java-array-min-max) - [Finding Min/Max in an Array with Java](https://www.baeldung.com/java-array-min-max)
- [Internationalization and Localization in Java 8](https://www.baeldung.com/java-8-localization) - [Internationalization and Localization in Java 8](https://www.baeldung.com/java-8-localization)
- [Generalized Target-Type Inference in Java](https://www.baeldung.com/java-generalized-target-type-inference) - [Generalized Target-Type Inference in Java](https://www.baeldung.com/java-generalized-target-type-inference)
- [Monads in Java](https://www.baeldung.com/java-monads) - [Monads in Java Optional](https://www.baeldung.com/java-monads)
- [[More -->]](/core-java-modules/core-java-8-2) - [[More -->]](/core-java-modules/core-java-8-2)

View File

@ -3,3 +3,4 @@
This module contains articles about Java array fundamentals. They assume no previous background knowledge on working with arrays. This module contains articles about Java array fundamentals. They assume no previous background knowledge on working with arrays.
### Relevant Articles: ### Relevant Articles:
- [Arrays mismatch() Method in Java](https://www.baeldung.com/java-arrays-mismatch)

View File

@ -7,4 +7,5 @@
- [Creating Custom Iterator in Java](https://www.baeldung.com/java-creating-custom-iterator) - [Creating Custom Iterator in Java](https://www.baeldung.com/java-creating-custom-iterator)
- [Difference Between Arrays.sort() and Collections.sort()](https://www.baeldung.com/java-arrays-collections-sort-methods) - [Difference Between Arrays.sort() and Collections.sort()](https://www.baeldung.com/java-arrays-collections-sort-methods)
- [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration) - [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration)
- [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-4) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-4)

View File

@ -1,2 +1,3 @@
## Relevant Articles ## Relevant Articles
- [Difference Between putIfAbsent() and computeIfAbsent() in Javas Map](https://www.baeldung.com/java-map-putifabsent-computeifabsent) - [Difference Between putIfAbsent() and computeIfAbsent() in Javas Map](https://www.baeldung.com/java-map-putifabsent-computeifabsent)
- [How to Write Hashmap to CSV File](https://www.baeldung.com/java-write-hashmap-csv)

View File

@ -0,0 +1,3 @@
### Relevant Articles:
- [Why wait() Requires Synchronization?](https://www.baeldung.com/java-wait-necessary-synchronization)

View File

@ -10,4 +10,5 @@ This module contains articles about basic Java concurrency.
- [Returning a Value After Finishing Threads Job in Java](https://www.baeldung.com/java-return-value-after-thread-finish) - [Returning a Value After Finishing Threads Job in Java](https://www.baeldung.com/java-return-value-after-thread-finish)
- [CompletableFuture and ThreadPool in Java](https://www.baeldung.com/java-completablefuture-threadpool) - [CompletableFuture and ThreadPool in Java](https://www.baeldung.com/java-completablefuture-threadpool)
- [CompletableFuture allOf().join() vs. CompletableFuture.join()](https://www.baeldung.com/java-completablefuture-allof-join) - [CompletableFuture allOf().join() vs. CompletableFuture.join()](https://www.baeldung.com/java-completablefuture-allof-join)
- [Retry Logic with CompletableFuture](https://www.baeldung.com/java-completablefuture-retry-logic)
- [[<-- Prev]](../core-java-concurrency-basic-2) - [[<-- Prev]](../core-java-concurrency-basic-2)

View File

@ -0,0 +1,100 @@
package com.baeldung.concurrent.completablefuturelist;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.stream.Collectors;
public class Application {
ScheduledExecutorService asyncOperationEmulation;
Application initialize() {
asyncOperationEmulation = Executors.newScheduledThreadPool(10);
return this;
}
CompletableFuture<String> asyncOperation(String operationId) {
CompletableFuture<String> cf = new CompletableFuture<>();
asyncOperationEmulation.submit(() -> {
// The following lines simulate an exception happening on the 567th operation
// if (operationId.endsWith("567")) {
// cf.completeExceptionally(new Exception("Error on operation " + operationId));
// return;
// }
try {
Thread.sleep(100);
cf.complete(operationId);
} catch (InterruptedException e) {
System.err.println("Thread interrupted error");
cf.completeExceptionally(e);
}
});
return cf;
}
void startNaive() {
List<CompletableFuture<String>> futures = new ArrayList<>();
for (int i = 1; i <= 1000; i++) {
String operationId = "Naive-Operation-" + i;
futures.add(asyncOperation(operationId));
}
CompletableFuture<List<String>> aggregate = CompletableFuture.completedFuture(new ArrayList<>());
for (CompletableFuture<String> future : futures) {
aggregate = aggregate.thenCompose(list -> {
try {
list.add(future.get());
return CompletableFuture.completedFuture(list);
} catch (Exception e) {
final CompletableFuture<List<String>> excFuture = new CompletableFuture<>();
excFuture.completeExceptionally(e);
return excFuture;
}
});
}
try {
final List<String> results = aggregate.join();
System.out.println("Printing first 10 results");
for (int i = 0; i < 10; i++) {
System.out.println("Finished " + results.get(i));
}
} finally {
close();
}
}
void start() {
List<CompletableFuture<String>> futures = new ArrayList<>();
for (int i = 1; i <= 1000; i++) {
String operationId = "Operation-" + i;
futures.add(asyncOperation(operationId));
}
CompletableFuture<?>[] futuresArray = futures.toArray(new CompletableFuture<?>[0]);
CompletableFuture<List<String>> listFuture = CompletableFuture.allOf(futuresArray).thenApply(v -> futures.stream().map(CompletableFuture::join).collect(Collectors.toList()));
try {
final List<String> results = listFuture.join();
System.out.println("Printing first 10 results");
for (int i = 0; i < 10; i++) {
System.out.println("Finished " + results.get(i));
}
} finally {
close();
}
}
void close() {
asyncOperationEmulation.shutdownNow();
}
public static void main(String[] args) {
new Application().initialize()
// Switch between .startNaive() and .start() to test both implementations
// .startNaive();
.start();
}
}

View File

@ -12,6 +12,7 @@ This module contains articles about Java Concurrency that are also part of an Eb
- [Guide to the Volatile Keyword in Java](https://www.baeldung.com/java-volatile) - [Guide to the Volatile Keyword in Java](https://www.baeldung.com/java-volatile)
- [A Guide to the Java ExecutorService](https://www.baeldung.com/java-executor-service-tutorial) - [A Guide to the Java ExecutorService](https://www.baeldung.com/java-executor-service-tutorial)
- [Guide To CompletableFuture](https://www.baeldung.com/java-completablefuture) - [Guide To CompletableFuture](https://www.baeldung.com/java-completablefuture)
- [How To Manage Timeout for CompletableFuture](https://www.baeldung.com/java-completablefuture-timeout)
### NOTE: ### NOTE:

View File

@ -35,6 +35,21 @@
<artifactId>simplemagic</artifactId> <artifactId>simplemagic</artifactId>
<version>${simplemagic.version}</version> <version>${simplemagic.version}</version>
</dependency> </dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</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> </dependencies>
<build> <build>
@ -62,5 +77,6 @@
<jmime-magic.version>0.1.5</jmime-magic.version> <jmime-magic.version>0.1.5</jmime-magic.version>
<jodd-util.version>6.2.1</jodd-util.version> <jodd-util.version>6.2.1</jodd-util.version>
<simplemagic.version>1.17</simplemagic.version> <simplemagic.version>1.17</simplemagic.version>
<jmh.version>1.37</jmh.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,112 @@
package com.baeldung.zip;
import java.io.*;
import java.util.concurrent.TimeUnit;
import java.util.*;
import java.util.zip.*;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 1, time = 2, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(value = 1)
public class ZipBenchmark {
public static final int NUM_OF_FILES = 10;
public static final int DATA_SIZE = 204800;
@State(Scope.Thread)
public static class SourceState {
public File compressedFile;
@Setup(Level.Trial)
public void setup() throws IOException {
ZipSampleFileStore sampleFileStore = new ZipSampleFileStore(NUM_OF_FILES, DATA_SIZE);
compressedFile = sampleFileStore.getFile();
}
@TearDown(Level.Trial)
public void cleanup() {
if (compressedFile.exists()) {
compressedFile.delete();
}
}
}
@Benchmark
public static void readAllEntriesByZipFile(SourceState sourceState, Blackhole blackhole) throws IOException {
try (ZipFile zipFile = new ZipFile(sourceState.compressedFile)) {
Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
while (zipEntries.hasMoreElements()) {
ZipEntry zipEntry = zipEntries.nextElement();
try (InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(zipEntry))) {
blackhole.consume(ZipSampleFileStore.getString(inputStream));
}
}
}
}
@Benchmark
public static void readAllEntriesByZipInputStream(SourceState sourceState, Blackhole blackhole) throws IOException {
try (
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceState.compressedFile));
ZipInputStream zipInputStream = new ZipInputStream(bis)
) {
ZipEntry entry;
while ((entry = zipInputStream.getNextEntry()) != null) {
blackhole.consume(ZipSampleFileStore.getString(zipInputStream));
}
}
}
@Benchmark
public static void readLastEntryByZipFile(SourceState sourceState, Blackhole blackhole) throws IOException {
try (ZipFile zipFile = new ZipFile(sourceState.compressedFile)) {
ZipEntry zipEntry = zipFile.getEntry(getLastEntryName());
try (InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(zipEntry))) {
blackhole.consume(ZipSampleFileStore.getString(inputStream));
}
}
}
@Benchmark
public static void readLastEntryByZipInputStream(SourceState sourceState, Blackhole blackhole) throws IOException {
try (
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceState.compressedFile));
ZipInputStream zipInputStream = new ZipInputStream(bis)
) {
ZipEntry entry;
while ((entry = zipInputStream.getNextEntry()) != null) {
if (Objects.equals(entry.getName(), getLastEntryName())){
blackhole.consume(ZipSampleFileStore.getString(zipInputStream));
}
}
}
}
private static String getLastEntryName() {
return String.format(ZipSampleFileStore.ENTRY_NAME_PATTERN, NUM_OF_FILES);
}
public static void main(String[] args) throws Exception {
Options options = new OptionsBuilder()
.include(ZipBenchmark.class.getSimpleName()).threads(1)
.shouldFailOnError(true)
.shouldDoGC(true)
.jvmArgs("-server").build();
new Runner(options).run();
}
}

View File

@ -0,0 +1,70 @@
package com.baeldung.zip;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.IOUtils;
public class ZipSampleFileStore {
public static final String ENTRY_NAME_PATTERN = "str-data-%s.txt";
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
private final File file;
private final List<String> dataList;
public ZipSampleFileStore(int numOfFiles, int fileSize) throws IOException {
dataList = new ArrayList<>(numOfFiles);
file = File.createTempFile("zip-sample", "");
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(file))) {
for (int idx=0; idx<=numOfFiles; idx++) {
byte[] data = createRandomStringInByte(fileSize);
dataList.add(new String(data, DEFAULT_ENCODING));
ZipEntry entry = new ZipEntry(String.format(ENTRY_NAME_PATTERN, idx));
zos.putNextEntry(entry);
zos.write(data);
zos.closeEntry();
}
}
}
public static byte[] createRandomStringInByte(int size) {
Random random = new Random();
byte[] data = new byte[size];
for (int n = 0; n < data.length; n++) {
char randomChar;
int choice = random.nextInt(2); // 0 for uppercase, 1 for lowercase
if (choice == 0) {
randomChar = (char) ('A' + random.nextInt(26)); // 'A' to 'Z'
} else {
randomChar = (char) ('a' + random.nextInt(26)); // 'a' to 'z'
}
data[n] = (byte) randomChar;
}
return data;
}
public File getFile() {
return file;
}
public List<String> getDataList() {
return dataList;
}
public static String getString(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
IOUtils.copy(inputStream, byteArrayOutputStream);
return byteArrayOutputStream.toString(DEFAULT_ENCODING);
}
}

View File

@ -0,0 +1,83 @@
package com.baeldung.zip;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.*;
import java.util.*;
import java.util.zip.*;
import org.junit.*;
public class ZipUnitTest {
private static File compressedFile;
private static List<String> dataList = new ArrayList<>();
@BeforeClass
public static void prepareData() throws IOException {
ZipSampleFileStore sampleFileStore = new ZipSampleFileStore(ZipBenchmark.NUM_OF_FILES, ZipBenchmark.DATA_SIZE);
compressedFile = sampleFileStore.getFile();
dataList = sampleFileStore.getDataList();
}
@Test
public void whenCreateZipFile_thenCompressedSizeShouldBeLessThanOriginal() throws IOException {
byte[] data = ZipSampleFileStore.createRandomStringInByte(10240);
File file = File.createTempFile("zip-temp", "");
try (
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
ZipOutputStream zos = new ZipOutputStream(bos)
) {
ZipEntry zipEntry = new ZipEntry("zip-entry.txt");
zos.putNextEntry(zipEntry);
zos.write(data);
zos.closeEntry();
assertThat(file.length()).isLessThan(data.length);
}
finally {
file.delete();
}
}
@Test
public void whenReadAllEntriesViaZipFile_thenDataIsEqualtoTheSource() throws IOException {
try (ZipFile zipFile = new ZipFile(compressedFile)) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
List<? extends ZipEntry> entryList = Collections.list(entries);
for (int idx=0; idx<entryList.size(); idx++) {
ZipEntry zipEntry = entryList.get(idx);
try (InputStream inputStream = zipFile.getInputStream(zipEntry)) {
String actual = ZipSampleFileStore.getString(inputStream);
assertThat(actual).as("Data for ZIP entry: " + zipEntry.getName()).isEqualTo(dataList.get(idx));
}
}
}
}
@Test
public void whenReadAllEntriesViaZipInputStream_thenDataIsEqualtoTheSource() throws IOException {
int idx = 0;
try (
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(compressedFile));
ZipInputStream zipInputStream = new ZipInputStream(bis)
) {
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
String actual = ZipSampleFileStore.getString(zipInputStream);
assertThat(actual).as("Data for ZIP entry: " + zipEntry.getName()).isEqualTo(dataList.get(idx++));
}
}
}
@AfterClass
public static void cleanup() {
if (compressedFile.exists()) {
compressedFile.delete();
}
}
}

View File

@ -0,0 +1,2 @@
I'm going to Alabama
Alabama is a state in the US

View File

@ -0,0 +1 @@
Dreams from My Father by Barack Obama

View File

@ -0,0 +1 @@
Harry Potter and the Chamber of Secrets

View File

@ -0,0 +1,64 @@
package com.baeldung.printwritervsfilewriter;
import static org.junit.jupiter.api.Assertions.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import org.junit.jupiter.api.Test;
public class PrintWriterVsFilePrinterUnitTest {
@Test
public void whenWritingToTextFileUsingFileWriter_thenTextMatches() throws IOException {
String result = "Harry Potter and the Chamber of Secrets";
File file = new File("potter.txt");
try (FileWriter fw = new FileWriter(file);) {
fw.write("Harry Potter and the Chamber of Secrets");
}
try (BufferedReader reader = new BufferedReader(new FileReader(file));) {
String actualData = reader.readLine();
assertEquals(result, actualData);
}
}
@Test
public void whenWritingToTextFileUsingPrintWriterPrintf_thenTextMatches() throws IOException {
String result = "Dreams from My Father by Barack Obama";
File file = new File("dream.txt");
try (PrintWriter pw = new PrintWriter(file);) {
String author = "Barack Obama";
pw.printf("Dreams from My Father by %s", author);
assertTrue(!pw.checkError());
}
try (BufferedReader reader = new BufferedReader(new FileReader(file));) {
String actualData = reader.readLine();
assertEquals(result, actualData);
}
}
@Test
public void whenWritingToTextFileUsingPrintWriterPrintln_thenTextMatches() throws IOException {
String result = "I'm going to Alabama\nAlabama is a state in the US\n";
try (PrintWriter pw = new PrintWriter("alabama.txt");) {
pw.println("I'm going to Alabama");
pw.println("Alabama is a state in the US");
}
Path path = Paths.get("alabama.txt");
String actualData = new String(Files.readAllBytes(path));
assertEquals(result, actualData);
}
}

View File

@ -4,3 +4,4 @@
- [Aggregate Runtime Exceptions in Java Streams](https://www.baeldung.com/java-streams-aggregate-exceptions) - [Aggregate Runtime Exceptions in Java Streams](https://www.baeldung.com/java-streams-aggregate-exceptions)
- [Streams vs. Loops in Java](https://www.baeldung.com/java-streams-vs-loops) - [Streams vs. Loops in Java](https://www.baeldung.com/java-streams-vs-loops)
- [Partition a Stream in Java](https://www.baeldung.com/java-partition-stream) - [Partition a Stream in Java](https://www.baeldung.com/java-partition-stream)
- [Taking Every N-th Element from Finite and Infinite Streams in Java](https://www.baeldung.com/java-nth-element-finite-infinite-streams)

View File

@ -13,3 +13,4 @@ This module contains articles about string-related algorithms.
- [Find the Most Frequent Characters in a String](https://www.baeldung.com/java-string-find-most-frequent-characters) - [Find the Most Frequent Characters in a String](https://www.baeldung.com/java-string-find-most-frequent-characters)
- [Checking If a String Is a Repeated Substring](https://www.baeldung.com/java-repeated-substring) - [Checking If a String Is a Repeated Substring](https://www.baeldung.com/java-repeated-substring)
- [Check if Letter Is Emoji With Java](https://www.baeldung.com/java-check-letter-emoji) - [Check if Letter Is Emoji With Java](https://www.baeldung.com/java-check-letter-emoji)
- [Wrapping a String After a Number of Characters Word-Wise](https://www.baeldung.com/java-wrap-string-number-characters-word-wise)

View File

@ -3,3 +3,5 @@
- [Convert String to Int Using Encapsulation](https://www.baeldung.com/java-encapsulation-convert-string-to-int) - [Convert String to Int Using Encapsulation](https://www.baeldung.com/java-encapsulation-convert-string-to-int)
- [HashMap with Multiple Values for the Same Key](https://www.baeldung.com/java-hashmap-multiple-values-per-key) - [HashMap with Multiple Values for the Same Key](https://www.baeldung.com/java-hashmap-multiple-values-per-key)
- [Split Java String Into Key-Value Pairs](https://www.baeldung.com/java-split-string-map) - [Split Java String Into Key-Value Pairs](https://www.baeldung.com/java-split-string-map)
- [How to Center Text Output in Java](https://www.baeldung.com/java-center-text-output)
- [How to Convert an Object to String](https://www.baeldung.com/java-object-string-representation)

View File

@ -11,4 +11,4 @@
- [Check if a String Has All Unique Characters in Java](https://www.baeldung.com/java-check-string-all-unique-chars) - [Check if a String Has All Unique Characters in Java](https://www.baeldung.com/java-check-string-all-unique-chars)
- [Performance Comparison Between Different Java String Concatenation Methods](https://www.baeldung.com/java-string-concatenation-methods) - [Performance Comparison Between Different Java String Concatenation Methods](https://www.baeldung.com/java-string-concatenation-methods)
- [Replacing Single Quote with \ in Java String](https://www.baeldung.com/java-replacing-single-quote-string) - [Replacing Single Quote with \ in Java String](https://www.baeldung.com/java-replacing-single-quote-string)
- [Check if a String Contains a Number Value in Java](https://www.baeldung.com/java-string-number-presence)

View File

@ -1,2 +1,4 @@
### Relevant Articles: ### Relevant Articles:
- [How to Center Text Output in Java](https://www.baeldung.com/java-center-text-output)
- [Capitalize the First Letter of Each Word in a String](https://www.baeldung.com/java-string-initial-capital-letter-every-word)

View File

@ -0,0 +1,14 @@
package com.baeldung.passstringbyreference;
public class Dummy {
String dummyString;
public String getDummyString() {
return dummyString;
}
public void setDummyString(String dummyString) {
this.dummyString = dummyString;
}
}

View File

@ -0,0 +1,85 @@
package com.baeldung.passstringbyreference;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import org.junit.jupiter.api.Test;
class PassStringUnitTest {
@Test
void givenAString_whenPassedToVoidMethod_thenStringIsNotModified() {
String s = "hello";
concatStringWithNoReturn(s);
assertEquals("hello", s);
}
void concatStringWithNoReturn(String input) {
input += " world";
assertEquals("hello world", input);
}
@Test
void givenAString_whenPassedToMethodAndReturnNewString_thenStringIsModified() {
String s = "hello";
assertEquals("hello world", concatStringWithReturn(s));
}
String concatStringWithReturn(String input) {
return input + " world";
}
@Test
void givenAString_whenPassStringBuilderToVoidMethod_thenConcatNewStringOk() {
StringBuilder builder = new StringBuilder("hello");
concatWithStringBuilder(builder);
assertEquals("hello world", builder.toString());
}
void concatWithStringBuilder(StringBuilder input) {
input.append(" world");
}
@Test
void givenAString_whenPassStringBufferToVoidMethod_thenConcatNewStringOk() {
StringBuffer builder = new StringBuffer("hello");
concatWithStringBuffer(builder);
assertEquals("hello world", builder.toString());
}
void concatWithStringBuffer(StringBuffer input) {
input.append(" world");
}
@Test
void givenObjectWithStringField_whenSetDifferentValue_thenObjectIsModified() {
Dummy dummy = new Dummy();
assertNull(dummy.getDummyString());
modifyStringValueInInputObject(dummy, "hello world");
assertEquals("hello world", dummy.getDummyString());
}
void modifyStringValueInInputObject(Dummy dummy, String dummyString) {
dummy.setDummyString(dummyString);
}
@Test
void givenObjectWithStringField_whenSetDifferentValueWithStringBuilder_thenSetStringInNewObject() {
assertEquals("hello world", getDummy("hello", "world").getDummyString());
}
Dummy getDummy(String hello, String world) {
StringBuilder builder = new StringBuilder();
builder.append(hello)
.append(" ")
.append(world);
Dummy dummy = new Dummy();
dummy.setDummyString(builder.toString());
return dummy;
}
}

View File

@ -3,4 +3,4 @@
- [Transferring a File Through SFTP in Java](https://www.baeldung.com/java-file-sftp) - [Transferring a File Through SFTP in Java](https://www.baeldung.com/java-file-sftp)
- [How to Create Password-Protected Zip Files and Unzip Them in Java](https://www.baeldung.com/java-password-protected-zip-unzip) - [How to Create Password-Protected Zip Files and Unzip Them in Java](https://www.baeldung.com/java-password-protected-zip-unzip)
- [How to Create CSV File from POJO with Custom Column Headers and Positions](https://www.baeldung.com/java-create-csv-pojo-customize-columns)

View File

@ -22,6 +22,7 @@ public class EditorUnitTest {
loadAndVerifyTestData(entityManagerFactory, editor); loadAndVerifyTestData(entityManagerFactory, editor);
} }
*/ */
@Test @Test
public void givenNeo4j_WhenEntitiesCreated_thenCanBeRetrieved() throws Exception { public void givenNeo4j_WhenEntitiesCreated_thenCanBeRetrieved() throws Exception {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("ogm-neo4j"); EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("ogm-neo4j");

View File

@ -106,6 +106,7 @@
<module>spring-jpa</module> <module>spring-jpa</module>
<module>spring-jpa-2</module> <module>spring-jpa-2</module>
<module>spring-jdbc</module> <module>spring-jdbc</module>
<module>spring-jdbc-2</module>
<module>spring-jooq</module> <module>spring-jooq</module>
<module>spring-mybatis</module> <module>spring-mybatis</module>
<module>spring-persistence-simple</module> <module>spring-persistence-simple</module>

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring-jdbc-2</artifactId>
<version>1.0-SNAPSHOT</version>
<name>spring-jdbc-2</name>
<description>Demo project for Spring Jdbc</description>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-3</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
<properties>
<spring-boot.version>3.2.0-SNAPSHOT</spring-boot.version>
<junit-jupiter.version>5.10.0</junit-jupiter.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -0,0 +1,14 @@
package com.baeldung.jdbcclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = "com.baledung.jdbcclient")
public class JdbcClientDemoApplication {
public static void main(String[] args) {
SpringApplication.run(JdbcClientDemoApplication.class, args);
}
}

View File

@ -0,0 +1,95 @@
package com.baeldung.jdbcclient.dao;
import com.baeldung.jdbcclient.model.Student;
import com.baeldung.jdbcclient.model.StudentResultExtractor;
import com.baeldung.jdbcclient.model.StudentRowMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowCountCallbackHandler;
import org.springframework.jdbc.core.simple.JdbcClient;
import org.springframework.stereotype.Repository;
import java.sql.Types;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Repository
public class StudentDao {
private static final Logger logger = LoggerFactory.getLogger(StudentDao.class);
@Autowired
private JdbcClient jdbcClient;
public Integer insertWithSetParamWithNamedParamAndSqlType(Student student) {
String sql = "INSERT INTO student (student_name, age, grade, gender, state)"
+ "VALUES (:name, :age, :grade, :gender, :state)";
Integer noOfrowsAffected = this.jdbcClient.sql(sql)
.param("name", student.getStudentName(), Types.VARCHAR)
.param("age", student.getAge(), Types.INTEGER)
.param("grade", student.getGrade(), Types.INTEGER)
.param("gender", student.getStudentGender(), Types.VARCHAR)
.param("state", student.getState(), Types.VARCHAR)
.update();
logger.info("No. of rows affected: " + noOfrowsAffected);
return noOfrowsAffected;
}
public List<Student> getStudentsOfGradeStateAndGenderWithPositionalParams(int grade, String state, String gender) {
String sql = "select student_id, student_name, age, grade, gender, state from student"
+ " where grade = ? and state = ? and gender = ?";
return jdbcClient.sql(sql)
.param(grade)
.param(state)
.param(gender)
.query(new StudentRowMapper()).list();
}
public List<Student> getStudentsOfGradeStateAndGenderWithParamIndex(int grade, String state, String gender) {
String sql = "select student_id, student_name, age, grade, gender, state from student"
+ " where grade = ? and state = ? and gender = ?";
return jdbcClient.sql(sql)
.param(1,grade)
.param(2, state)
.param(3, gender)
.query(new StudentResultExtractor());
}
public Student getStudentsOfGradeStateAndGenderWithParamsInVarargs(int grade, String state, String gender) {
String sql = "select student_id, student_name, age, grade, gender, state from student"
+ " where grade = ? and state = ? and gender = ? limit 1";
return jdbcClient.sql(sql)
.params(grade, state, gender)
.query(new StudentRowMapper()).single();
}
public Optional<Student> getStudentsOfGradeStateAndGenderWithParamsInList(List params) {
String sql = "select student_id, student_name, age, grade, gender, state from student"
+ " where grade = ? and state = ? and gender = ? limit 1";
return jdbcClient.sql(sql)
.params(params)
.query(new StudentRowMapper()).optional();
}
public int getCountOfStudentsOfGradeStateAndGenderWithNamedParam(int grade, String state, String gender) {
String sql = "select student_id, student_name, age, grade, gender, state from student"
+ " where grade = :grade and state = :state and gender = :gender";
RowCountCallbackHandler countCallbackHandler = new RowCountCallbackHandler();
jdbcClient.sql(sql)
.param("grade", grade)
.param("state", state)
.param("gender", gender)
.query(countCallbackHandler);
return countCallbackHandler.getRowCount();
}
public List<Student> getStudentsOfGradeStateAndGenderWithParamMap(Map<String, ?> paramMap) {
String sql = "select student_id, student_name, age, grade, gender, state from student"
+ " where grade = :grade and state = :state and gender = :gender";
return jdbcClient.sql(sql)
.params(paramMap)
.query(new StudentRowMapper()).list();
}
}

View File

@ -0,0 +1,60 @@
package com.baeldung.jdbcclient.model;
public class Student {
private Integer studentId;
private String studentName;
private String studentGender;
private Integer age;
private Integer grade;
public Integer getStudentId() {
return studentId;
}
public void setStudentId(Integer studentId) {
this.studentId = studentId;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getStudentGender() {
return studentGender;
}
public void setStudentGender(String studentGender) {
this.studentGender = studentGender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getGrade() {
return grade;
}
public void setGrade(Integer grade) {
this.grade = grade;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
private String state;
}

View File

@ -0,0 +1,26 @@
package com.baeldung.jdbcclient.model;
import org.springframework.jdbc.core.ResultSetExtractor;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class StudentResultExtractor implements ResultSetExtractor<List<Student>> {
@Override
public List<Student> extractData(ResultSet rs) throws SQLException {
List<Student> students = new ArrayList<Student>();
while(rs.next()) {
Student student = new Student();
student.setStudentId(rs.getInt("student_id"));
student.setStudentName(rs.getString("student_name"));
student.setAge(rs.getInt("age"));
student.setStudentGender(rs.getString("gender"));
student.setGrade(rs.getInt("grade"));
student.setState(rs.getString("state"));
students.add(student);
}
return students;
}
}

View File

@ -0,0 +1,20 @@
package com.baeldung.jdbcclient.model;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
public class StudentRowMapper implements RowMapper<Student> {
@Override
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Student();
student.setStudentId(rs.getInt("student_id"));
student.setStudentName(rs.getString("student_name"));
student.setAge(rs.getInt("age"));
student.setStudentGender(rs.getString("gender"));
student.setGrade(rs.getInt("grade"));
student.setState(rs.getString("state"));
return student;
}
}

View File

@ -0,0 +1,5 @@
# DataSource Configuration
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=user
spring.datasource.password= # Leave this empty

View File

@ -0,0 +1 @@
DROP TABLE student;

View File

@ -0,0 +1,98 @@
CREATE TABLE student (
student_id INT AUTO_INCREMENT PRIMARY KEY,
student_name VARCHAR(255) NOT NULL,
age INT,
grade INT NOT NULL,
gender VARCHAR(10) NOT NULL,
state VARCHAR(100) NOT NULL
);
-- Student 1
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('John Smith', 18, 3, 'Male', 'California');
-- Student 2
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Emily Johnson', 17, 2, 'Female', 'New York');
-- Student 3
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Michael Davis', 4, 1, 'Male', 'Texas');
-- Student 4
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Sophia Martinez', 2, 1, 'Female', 'Florida');
-- Student 5
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('William Brown', 5, 5, 'Male', 'California');
-- Student 6
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Olivia Garcia', 4, 2, 'Female', 'Texas');
-- Student 7
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Ethan Rodriguez', 3, 1, 'Male', 'New York');
-- Student 8
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Ava Hernandez', 2, 1, 'Female', 'Florida');
-- Student 9
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('James Wilson', 5, 4, 'Male', 'Texas');
-- Student 10
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Emma Miller', 3, 1, 'Female', 'California');
-- Student 11
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Benjamin Brown', 4, 1, 'Male', 'New York');
-- Student 12
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Mia Smith', 2, 1, 'Female', 'Florida');
-- Student 13
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Daniel Johnson', 5, 4, 'Male', 'California');
-- Student 14
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Ava Davis', 4, 2, 'Female', 'Texas');
-- Student 15
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Matthew Martinez', 3, 1, 'Male', 'New York');
-- Student 16
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Sophia Taylor', 2, 1, 'Female', 'Florida');
-- Student 17
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Alexander White', 5, 4, 'Male', 'California');
-- Student 18
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Olivia Johnson', 4, 2, 'Female', 'Texas');
-- Student 19
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Christopher Lee', 3, 1, 'Male', 'New York');
-- Student 20
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Emma Wilson', 2, 1, 'Female', 'Florida');
-- Student 21
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Elijah Smith', 5, 3, 'Male', 'Texas');
-- Student 22
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Isabella Davis', 4, 2, 'Female', 'California');
-- Student 23
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Liam Johnson', 3, 1, 'Male', 'New York');
-- Student 24
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Olivia Garcia', 2, 1, 'Female', 'Florida');
-- Student 25
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Noah Rodriguez', 5, 3, 'Male', 'Texas');
-- Student 26
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Sophia Hernandez', 4, 2, 'Female', 'California');
-- Student 27
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Mason Smith', 3, 1, 'Male', 'New York');
-- Student 28
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Ava Taylor', 2, 1, 'Female', 'Florida');
-- Student 29
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('William Brown', 5, 5, 'Male', 'Texas');
-- Student 30
INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Olivia Martinez', 4, 4, 'Female', 'California');

View File

@ -0,0 +1,104 @@
package com.baeldung.jdbcclient;
import com.baeldung.jdbcclient.dao.StudentDao;
import com.baeldung.jdbcclient.model.Student;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.jdbc.Sql;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
@Sql(value = "/jdbcclient/student.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(value = "/jdbcclient/drop_student.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
@SpringBootTest(classes = JdbcClientDemoApplication.class)
@TestPropertySource(locations = {"classpath:jdbcclient/application.properties"})
public class JdbcClientUnitTest {
private static final Logger logger = LoggerFactory.getLogger(JdbcClientUnitTest.class);
@Autowired
private StudentDao studentDao;
@Test
void givenJdbcClient_whenInsertWithNamedParamAndSqlType_thenSuccess() {
logger.info("testing invoked successfully");
Student student = getSampleStudent("Johny Dep", 8, 4, "Male", "New York");
assertEquals(1, studentDao.insertWithSetParamWithNamedParamAndSqlType(student));
}
@Test
void givenJdbcClient_whenQueryWithPositionalParams_thenSuccess() {
logger.info("testing invoked successfully");
List<Student> students = studentDao.getStudentsOfGradeStateAndGenderWithPositionalParams(
1, "New York", "Male");
logger.info("number of students fetched " + students.size());
assertEquals(6, students.size());
}
@Test
void givenJdbcClient_whenQueryWithParamsInVarargs_thenSuccess() {
logger.info("testing invoked successfully");
Student student = studentDao.getStudentsOfGradeStateAndGenderWithParamsInVarargs(
1, "New York", "Male");
assertNotNull(student);
}
@Test
void givenJdbcClient_whenQueryWithParamsInList_thenSuccess() {
logger.info("testing invoked successfully");
List params = List.of(1, "New York", "Male");
Optional<Student> optional = studentDao.getStudentsOfGradeStateAndGenderWithParamsInList(params);
if(optional.isPresent()) {
assertNotNull(optional.get());
} else {
assertThrows(NoSuchElementException.class, () -> optional.get());
}
}
@Test
void givenJdbcClient_whenQueryWithParamsIndex_thenSuccess() {
logger.info("testing invoked successfully");
List<Student> students = studentDao.getStudentsOfGradeStateAndGenderWithParamIndex(
1, "New York", "Male");
assertEquals(6, students.size());
}
@Test
void givenJdbcClient_whenQueryWithNamedParam_thenSuccess() {
logger.info("testing invoked successfully");
Integer count = studentDao.getCountOfStudentsOfGradeStateAndGenderWithNamedParam(
1, "New York", "Male");
logger.info("number of students fetched " + count);
assertEquals(6, count);
}
@Test
void givenJdbcClient_whenQueryWithParamMap_thenSuccess() {
logger.info("testing invoked successfully");
Map<String, ?> paramMap = Map.of(
"grade", 1,
"gender", "Male",
"state", "New York"
);
List<Student> students = studentDao.getStudentsOfGradeStateAndGenderWithParamMap(paramMap);
logger.info("number of students fetched " + students.size());
assertEquals(6, students.size());
}
private Student getSampleStudent(String name, int age, int grade, String gender, String state) {
Student student = new Student();
student.setStudentName(name);
student.setStudentGender(gender);
student.setAge(age);
student.setGrade(grade);
student.setState(state);
return student;
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="15 seconds" debug="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{ISO8601}]-[%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -349,7 +349,6 @@
<!-- <module>ethereum</module> --> <!-- JAVA-6001 --> <!-- <module>ethereum</module> --> <!-- JAVA-6001 -->
<!-- <module>gradle-modules</module> --> <!-- Not a maven project --> <!-- <module>gradle-modules</module> --> <!-- Not a maven project -->
<!-- <module>grails</module> --> <!-- Not a maven project -->
<!-- <module>guest</module> --> <!-- not to be built as its for guest articles --> <!-- <module>guest</module> --> <!-- not to be built as its for guest articles -->
<!-- <module>lagom</module> --> <!-- Not a maven project --> <!-- <module>lagom</module> --> <!-- Not a maven project -->
@ -362,7 +361,7 @@
<module>muleesb</module> <module>muleesb</module>
<module>web-modules/java-lite</module> <module>web-modules/java-lite</module>
<module>persistence-modules/deltaspike</module> <!-- delta spike it doesn't support yet the jakarta API--> <module>persistence-modules/deltaspike</module> <!-- delta spike it doesn't support yet the jakarta API-->
<module>persistence-modules/hibernate-ogm</module> <!-- hibernate-ogm wasn't updated because it doesn't support jakarta API --> <module>persistence-modules/hibernate-ogm</module> <!-- hibernate-ogm wasn't updated because a workaround for jakarta namespace wasn't found JAVA-20557 -->
<module>persistence-modules/spring-data-cassandra-reactive</module> <!--JAVA-21844--> <module>persistence-modules/spring-data-cassandra-reactive</module> <!--JAVA-21844-->
<module>java-nashorn</module> <module>java-nashorn</module>
<module>jeromq</module> <module>jeromq</module>
@ -523,7 +522,6 @@
<!-- <module>ethereum</module> --> <!-- JAVA-6001 --> <!-- <module>ethereum</module> --> <!-- JAVA-6001 -->
<!-- <module>gradle-modules</module> --> <!-- Not a maven project --> <!-- <module>gradle-modules</module> --> <!-- Not a maven project -->
<!-- <module>grails</module> --> <!-- Not a maven project -->
<!-- <module>guest</module> --> <!-- not to be built as its for guest articles --> <!-- <module>guest</module> --> <!-- not to be built as its for guest articles -->
<!-- <module>lagom</module> --> <!-- Not a maven project --> <!-- <module>lagom</module> --> <!-- Not a maven project -->
@ -534,7 +532,7 @@
<module>muleesb</module> <module>muleesb</module>
<module>web-modules/java-lite</module> <module>web-modules/java-lite</module>
<module>persistence-modules/deltaspike</module> <!-- delta spike it doesn't support yet the jakarta API--> <module>persistence-modules/deltaspike</module> <!-- delta spike it doesn't support yet the jakarta API-->
<module>persistence-modules/hibernate-ogm</module> <!-- hibernate-ogm wasn't updated because it doesn't support jakarta API --> <module>persistence-modules/hibernate-ogm</module> <!-- hibernate-ogm wasn't updated because a workaround for jakarta namespace wasn't found JAVA-20557 -->
<module>persistence-modules/spring-data-cassandra-reactive</module> <!--JAVA-21844--> <module>persistence-modules/spring-data-cassandra-reactive</module> <!--JAVA-21844-->
<module>java-nashorn</module> <module>java-nashorn</module>
<module>jeromq</module> <module>jeromq</module>
@ -1211,7 +1209,6 @@
<module>gradle-modules/gradle/maven-to-gradle</module> <module>gradle-modules/gradle/maven-to-gradle</module>
<module>persistence-modules/spring-data-neo4j</module> <module>persistence-modules/spring-data-neo4j</module>
<module>spring-actuator</module> <module>spring-actuator</module>
<module>gcp-firebase</module>
<module>spring-di-4</module> <module>spring-di-4</module>
<module>spring-kafka-2</module> <module>spring-kafka-2</module>
<!--<module>java-panama</module> Java-19 module--> <!--<module>java-panama</module> Java-19 module-->

View File

@ -0,0 +1,2 @@
## Relevant Articles
- [Spring Boot 3.1s ConnectionDetails Abstraction](https://www.baeldung.com/spring-boot-3-1-connectiondetails-abstraction)

View File

@ -8,3 +8,4 @@
- [HTTP Interface in Spring 6](https://www.baeldung.com/spring-6-http-interface) - [HTTP Interface in Spring 6](https://www.baeldung.com/spring-6-http-interface)
- [Working with Virtual Threads in Spring 6](https://www.baeldung.com/spring-6-virtual-threads) - [Working with Virtual Threads in Spring 6](https://www.baeldung.com/spring-6-virtual-threads)
- [Docker Compose Support in Spring Boot 3](https://www.baeldung.com/ops/docker-compose-support-spring-boot) - [Docker Compose Support in Spring Boot 3](https://www.baeldung.com/ops/docker-compose-support-spring-boot)
- [A Guide to RestClient in Spring Boot](https://www.baeldung.com/spring-boot-restclient)

View File

@ -1,7 +1,6 @@
### Relevant Articles: ### Relevant Articles:
- [HttpMessageNotWritableException: No Converter for [class …] With Preset Content-Type](https://www.baeldung.com/spring-no-converter-with-preset) - [HttpMessageNotWritableException: No Converter for [class …] With Preset Content-Type](https://www.baeldung.com/spring-no-converter-with-preset)
- [Spring Boot: Customize the Jackson ObjectMapper](https://www.baeldung.com/spring-boot-customize-jackson-objectmapper)
- [“HttpMessageNotWritableException: No converter found for return value of type”](https://www.baeldung.com/spring-no-converter-found) - [“HttpMessageNotWritableException: No converter found for return value of type”](https://www.baeldung.com/spring-no-converter-found)
- [Creating a Read-Only Repository with Spring Data](https://www.baeldung.com/spring-data-read-only-repository) - [Creating a Read-Only Repository with Spring Data](https://www.baeldung.com/spring-data-read-only-repository)
- [Using JaVers for Data Model Auditing in Spring Data](https://www.baeldung.com/spring-data-javers-audit) - [Using JaVers for Data Model Auditing in Spring Data](https://www.baeldung.com/spring-data-javers-audit)

View File

@ -11,4 +11,5 @@ This module contains articles about Spring Boot with Spring Data
- [Spring Custom Property Editor](https://www.baeldung.com/spring-mvc-custom-property-editor) - [Spring Custom Property Editor](https://www.baeldung.com/spring-mvc-custom-property-editor)
- [Using @JsonComponent in Spring Boot](https://www.baeldung.com/spring-boot-jsoncomponent) - [Using @JsonComponent in Spring Boot](https://www.baeldung.com/spring-boot-jsoncomponent)
- [Guide To Running Logic on Startup in Spring](https://www.baeldung.com/running-setup-logic-on-startup-in-spring) - [Guide To Running Logic on Startup in Spring](https://www.baeldung.com/running-setup-logic-on-startup-in-spring)
- [Spring Boot: Customize the Jackson ObjectMapper](https://www.baeldung.com/spring-boot-customize-jackson-objectmapper)

View File

@ -1,10 +1,10 @@
package com.baeldung.boot.jackson.config; package com.baeldung.boot.jackson.config;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
public class CoffeeConstants { public class CoffeeConstants {
public static final String DATETIME_FORMAT = "dd-MM-yyyy HH:mm"; public static final String DATETIME_FORMAT = "dd-MM-yyyy HH:mm";

View File

@ -1,11 +1,12 @@
package com.baeldung.boot.jackson.config; package com.baeldung.boot.jackson.config;
import com.fasterxml.jackson.annotation.JsonInclude; import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; import com.fasterxml.jackson.annotation.JsonInclude;
@Configuration @Configuration
public class CoffeeCustomizerConfig { public class CoffeeCustomizerConfig {

View File

@ -1,12 +1,13 @@
package com.baeldung.boot.jackson.config; package com.baeldung.boot.jackson.config;
import com.fasterxml.jackson.annotation.JsonInclude; import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; import com.fasterxml.jackson.annotation.JsonInclude;
@Configuration @Configuration
public class CoffeeHttpConverterConfiguration { public class CoffeeHttpConverterConfiguration {

View File

@ -1,12 +1,13 @@
package com.baeldung.boot.jackson.config; package com.baeldung.boot.jackson.config;
import com.fasterxml.jackson.annotation.JsonInclude; import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; import com.fasterxml.jackson.annotation.JsonInclude;
@Configuration @Configuration
public class CoffeeJacksonBuilderConfig { public class CoffeeJacksonBuilderConfig {

View File

@ -1,13 +1,14 @@
package com.baeldung.boot.jackson.config; package com.baeldung.boot.jackson.config;
import com.fasterxml.jackson.annotation.JsonInclude; import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@Configuration @Configuration
public class CoffeeObjectMapperConfig { public class CoffeeObjectMapperConfig {

View File

@ -1,19 +1,19 @@
package com.baeldung.boot.jackson.config; package com.baeldung.boot.jackson.config;
import com.fasterxml.jackson.databind.Module; import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySource;
import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@Configuration @Configuration
@PropertySource("classpath:coffee.properties") @PropertySource("classpath:coffee.properties")
public class CoffeeRegisterModuleConfig { public class CoffeeRegisterModuleConfig {
@Bean @Bean
public Module javaTimeModule() { public JavaTimeModule javaTimeModule() {
JavaTimeModule module = new JavaTimeModule(); JavaTimeModule module = new JavaTimeModule();
module.addSerializer(LOCAL_DATETIME_SERIALIZER); module.addSerializer(LOCAL_DATETIME_SERIALIZER);
return module; return module;

View File

@ -1,11 +1,12 @@
package com.baeldung.boot.jackson.controller; package com.baeldung.boot.jackson.controller;
import com.baeldung.boot.jackson.model.Coffee; import static com.baeldung.boot.jackson.config.CoffeeConstants.FIXED_DATE;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import static com.baeldung.boot.jackson.config.CoffeeConstants.FIXED_DATE; import com.baeldung.boot.jackson.model.Coffee;
@RestController @RestController
public class CoffeeController { public class CoffeeController {

View File

@ -1,15 +1,16 @@
package com.baeldung.boot.jackson.app; package com.baeldung.boot.jackson.app;
import com.baeldung.boot.jackson.config.CoffeeConstants; import static com.baeldung.boot.jackson.config.CoffeeConstants.FIXED_DATE;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.format.DateTimeFormatter;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.client.TestRestTemplate;
import java.time.format.DateTimeFormatter; import com.baeldung.boot.jackson.config.CoffeeConstants;
import static com.baeldung.boot.jackson.config.CoffeeConstants.FIXED_DATE;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public abstract class AbstractCoffeeIntegrationTest { public abstract class AbstractCoffeeIntegrationTest {

View File

@ -1,8 +1,9 @@
package com.baeldung.boot.jackson.app; package com.baeldung.boot.jackson.app;
import com.baeldung.boot.jackson.config.CoffeeCustomizerConfig;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import com.baeldung.boot.jackson.config.CoffeeCustomizerConfig;
@Import(CoffeeCustomizerConfig.class) @Import(CoffeeCustomizerConfig.class)
public class CoffeeCustomizerIntegrationTest extends AbstractCoffeeIntegrationTest { public class CoffeeCustomizerIntegrationTest extends AbstractCoffeeIntegrationTest {
} }

View File

@ -1,8 +1,9 @@
package com.baeldung.boot.jackson.app; package com.baeldung.boot.jackson.app;
import com.baeldung.boot.jackson.config.CoffeeHttpConverterConfiguration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import com.baeldung.boot.jackson.config.CoffeeHttpConverterConfiguration;
@Import(CoffeeHttpConverterConfiguration.class) @Import(CoffeeHttpConverterConfiguration.class)
public class CoffeeHttpConverterIntegrationTest extends AbstractCoffeeIntegrationTest { public class CoffeeHttpConverterIntegrationTest extends AbstractCoffeeIntegrationTest {
} }

View File

@ -1,8 +1,9 @@
package com.baeldung.boot.jackson.app; package com.baeldung.boot.jackson.app;
import com.baeldung.boot.jackson.config.CoffeeJacksonBuilderConfig;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import com.baeldung.boot.jackson.config.CoffeeJacksonBuilderConfig;
@Import(CoffeeJacksonBuilderConfig.class) @Import(CoffeeJacksonBuilderConfig.class)
public class CoffeeJacksonBuilderIntegrationTest extends AbstractCoffeeIntegrationTest { public class CoffeeJacksonBuilderIntegrationTest extends AbstractCoffeeIntegrationTest {
} }

View File

@ -1,8 +1,9 @@
package com.baeldung.boot.jackson.app; package com.baeldung.boot.jackson.app;
import com.baeldung.boot.jackson.config.CoffeeObjectMapperConfig;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import com.baeldung.boot.jackson.config.CoffeeObjectMapperConfig;
@Import(CoffeeObjectMapperConfig.class) @Import(CoffeeObjectMapperConfig.class)
public class CoffeeObjectMapperIntegrationTest extends AbstractCoffeeIntegrationTest { public class CoffeeObjectMapperIntegrationTest extends AbstractCoffeeIntegrationTest {
} }

View File

@ -1,8 +1,9 @@
package com.baeldung.boot.jackson.app; package com.baeldung.boot.jackson.app;
import com.baeldung.boot.jackson.config.CoffeeRegisterModuleConfig;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import com.baeldung.boot.jackson.config.CoffeeRegisterModuleConfig;
@Import(CoffeeRegisterModuleConfig.class) @Import(CoffeeRegisterModuleConfig.class)
public class CoffeeRegisterModuleIntegrationTest extends AbstractCoffeeIntegrationTest { public class CoffeeRegisterModuleIntegrationTest extends AbstractCoffeeIntegrationTest {
} }

View File

@ -1,5 +1,10 @@
package com.baeldung.spring.cloud.springcloudcontractconsumer.controller; package com.baeldung.spring.cloud.springcloudcontractconsumer.controller;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -13,6 +18,7 @@ import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -26,6 +32,36 @@ public class BasicMathControllerIntegrationTest {
@Autowired @Autowired
private MockMvc mockMvc; private MockMvc mockMvc;
private static WireMockServer wireMockServer;
@BeforeClass
public static void setupClass() {
WireMockConfiguration wireMockConfiguration = WireMockConfiguration.options().port(8090); // Use the same port as in your code
wireMockServer = new WireMockServer(wireMockConfiguration);
wireMockServer.start();
}
@AfterClass
public static void teardownClass() {
wireMockServer.stop();
}
@Before
public void setup() {
wireMockServer.stubFor(get(urlEqualTo("/validate/prime-number?number=1"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("Odd")));
wireMockServer.stubFor(get(urlEqualTo("/validate/prime-number?number=2"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("Even")));
}
@Test @Test
public void given_WhenPassEvenNumberInQueryParam_ThenReturnEven() throws Exception { public void given_WhenPassEvenNumberInQueryParam_ThenReturnEven() throws Exception {

View File

@ -8,7 +8,8 @@ This module contains articles about core Spring Security
- [Prevent Cross-Site Scripting (XSS) in a Spring Application](https://www.baeldung.com/spring-prevent-xss) - [Prevent Cross-Site Scripting (XSS) in a Spring Application](https://www.baeldung.com/spring-prevent-xss)
- [Guide to the AuthenticationManagerResolver in Spring Security](https://www.baeldung.com/spring-security-authenticationmanagerresolver) - [Guide to the AuthenticationManagerResolver in Spring Security](https://www.baeldung.com/spring-security-authenticationmanagerresolver)
- [A Custom Spring SecurityConfigurer](https://www.baeldung.com/spring-security-custom-configurer) - [A Custom Spring SecurityConfigurer](https://www.baeldung.com/spring-security-custom-configurer)
- [HttpSecurity vs. WebSecurity in Spring Security](https://www.baeldung.com/spring-security-httpsecurity-vs-websecurity)
### Build the Project ### Build the Project
`mvn clean install` `mvn clean install`

View File

@ -7,3 +7,4 @@
- [Gray Box Testing Using the OAT Technique](https://www.baeldung.com/java-gray-box-orthogonal-array-testing) - [Gray Box Testing Using the OAT Technique](https://www.baeldung.com/java-gray-box-orthogonal-array-testing)
- [Unit Testing of System.in With JUnit](https://www.baeldung.com/java-junit-testing-system-in) - [Unit Testing of System.in With JUnit](https://www.baeldung.com/java-junit-testing-system-in)
- [Fail Maven Build if JUnit Coverage Falls Below Certain Threshold](https://www.baeldung.com/maven-junit-fail-build-coverage-threshold) - [Fail Maven Build if JUnit Coverage Falls Below Certain Threshold](https://www.baeldung.com/maven-junit-fail-build-coverage-threshold)
- [How to Mock Environment Variables in Unit Tests](https://www.baeldung.com/java-unit-testing-environment-variables)

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 658 B

After

Width:  |  Height:  |  Size: 658 B

View File

Before

Width:  |  Height:  |  Size: 659 B

After

Width:  |  Height:  |  Size: 659 B

View File

Before

Width:  |  Height:  |  Size: 767 B

After

Width:  |  Height:  |  Size: 767 B

View File

Before

Width:  |  Height:  |  Size: 755 B

After

Width:  |  Height:  |  Size: 755 B

View File

Before

Width:  |  Height:  |  Size: 726 B

After

Width:  |  Height:  |  Size: 726 B

View File

Before

Width:  |  Height:  |  Size: 701 B

After

Width:  |  Height:  |  Size: 701 B

View File

Before

Width:  |  Height:  |  Size: 806 B

After

Width:  |  Height:  |  Size: 806 B

View File

Before

Width:  |  Height:  |  Size: 778 B

After

Width:  |  Height:  |  Size: 778 B

View File

Before

Width:  |  Height:  |  Size: 300 B

After

Width:  |  Height:  |  Size: 300 B

View File

Before

Width:  |  Height:  |  Size: 835 B

After

Width:  |  Height:  |  Size: 835 B

View File

Before

Width:  |  Height:  |  Size: 834 B

After

Width:  |  Height:  |  Size: 834 B

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Some files were not shown because too many files have changed in this diff Show More