diff --git a/axon/pom.xml b/axon/pom.xml
index 32f12f8c43..ae199d27f9 100644
--- a/axon/pom.xml
+++ b/axon/pom.xml
@@ -71,7 +71,7 @@
- 4.5.17
+ 4.6.0
\ No newline at end of file
diff --git a/axon/src/main/java/com/baeldung/axon/gui/OrderRestEndpoint.java b/axon/src/main/java/com/baeldung/axon/gui/OrderRestEndpoint.java
index 9901f725fd..64058d5eca 100644
--- a/axon/src/main/java/com/baeldung/axon/gui/OrderRestEndpoint.java
+++ b/axon/src/main/java/com/baeldung/axon/gui/OrderRestEndpoint.java
@@ -92,6 +92,11 @@ public class OrderRestEndpoint {
return orderQueryService.findAllOrders();
}
+ @GetMapping(path = "/all-orders-streaming", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
+ public Flux allOrdersStreaming() {
+ return orderQueryService.allOrdersStreaming();
+ }
+
@GetMapping("/total-shipped/{product-id}")
public Integer totalShipped(@PathVariable("product-id") String productId) {
return orderQueryService.totalShipped(productId);
diff --git a/axon/src/main/java/com/baeldung/axon/querymodel/InMemoryOrdersEventHandler.java b/axon/src/main/java/com/baeldung/axon/querymodel/InMemoryOrdersEventHandler.java
index 202b48abfd..fbdf819961 100644
--- a/axon/src/main/java/com/baeldung/axon/querymodel/InMemoryOrdersEventHandler.java
+++ b/axon/src/main/java/com/baeldung/axon/querymodel/InMemoryOrdersEventHandler.java
@@ -17,7 +17,10 @@ import org.axonframework.config.ProcessingGroup;
import org.axonframework.eventhandling.EventHandler;
import org.axonframework.queryhandling.QueryHandler;
import org.axonframework.queryhandling.QueryUpdateEmitter;
+import org.reactivestreams.Publisher;
import org.springframework.stereotype.Service;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.HashMap;
@@ -101,6 +104,11 @@ public class InMemoryOrdersEventHandler implements OrdersEventHandler {
return new ArrayList<>(orders.values());
}
+ @QueryHandler
+ public Publisher handleStreaming(FindAllOrderedProductsQuery query) {
+ return Mono.fromCallable(orders::values).flatMapMany(Flux::fromIterable);
+ }
+
@QueryHandler
public Integer handle(TotalProductsShippedQuery query) {
return orders.values()
diff --git a/axon/src/main/java/com/baeldung/axon/querymodel/OrderQueryService.java b/axon/src/main/java/com/baeldung/axon/querymodel/OrderQueryService.java
index 192fc78226..ae391c3cb1 100644
--- a/axon/src/main/java/com/baeldung/axon/querymodel/OrderQueryService.java
+++ b/axon/src/main/java/com/baeldung/axon/querymodel/OrderQueryService.java
@@ -9,6 +9,7 @@ import org.axonframework.messaging.responsetypes.ResponseType;
import org.axonframework.messaging.responsetypes.ResponseTypes;
import org.axonframework.queryhandling.QueryGateway;
import org.axonframework.queryhandling.SubscriptionQueryResult;
+import org.reactivestreams.Publisher;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
@@ -34,6 +35,11 @@ public class OrderQueryService {
.collect(Collectors.toList()));
}
+ public Flux allOrdersStreaming() {
+ Publisher publisher = queryGateway.streamingQuery(new FindAllOrderedProductsQuery(), Order.class);
+ return Flux.from(publisher).map(OrderResponse::new);
+ }
+
public Integer totalShipped(String productId) {
return queryGateway.scatterGather(new TotalProductsShippedQuery(productId),
ResponseTypes.instanceOf(Integer.class), 10L, TimeUnit.SECONDS)
diff --git a/axon/src/main/java/com/baeldung/axon/querymodel/OrdersEventHandler.java b/axon/src/main/java/com/baeldung/axon/querymodel/OrdersEventHandler.java
index 0d4aad4c97..7e49abf93b 100644
--- a/axon/src/main/java/com/baeldung/axon/querymodel/OrdersEventHandler.java
+++ b/axon/src/main/java/com/baeldung/axon/querymodel/OrdersEventHandler.java
@@ -11,6 +11,7 @@ import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
import com.baeldung.axon.coreapi.queries.Order;
import com.baeldung.axon.coreapi.queries.OrderUpdatesQuery;
import com.baeldung.axon.coreapi.queries.TotalProductsShippedQuery;
+import org.reactivestreams.Publisher;
import java.util.List;
@@ -32,6 +33,8 @@ public interface OrdersEventHandler {
List handle(FindAllOrderedProductsQuery query);
+ Publisher handleStreaming(FindAllOrderedProductsQuery query);
+
Integer handle(TotalProductsShippedQuery query);
Order handle(OrderUpdatesQuery query);
diff --git a/axon/src/main/resources/order-api.http b/axon/src/main/resources/order-api.http
index d5f358cbb9..bd2a4289ab 100644
--- a/axon/src/main/resources/order-api.http
+++ b/axon/src/main/resources/order-api.http
@@ -10,6 +10,10 @@ POST http://localhost:8080/ship-unconfirmed-order
GET http://localhost:8080/all-orders
+### Receive all existing orders using a stream
+
+GET http://localhost:8080/all-orders-streaming
+
### Create Order with id 666a1661-474d-4046-8b12-8b5896312768
POST http://localhost:8080/order/666a1661-474d-4046-8b12-8b5896312768
diff --git a/axon/src/test/java/com/baeldung/axon/querymodel/AbstractOrdersEventHandlerUnitTest.java b/axon/src/test/java/com/baeldung/axon/querymodel/AbstractOrdersEventHandlerUnitTest.java
index daef0b684d..2396d0f10b 100644
--- a/axon/src/test/java/com/baeldung/axon/querymodel/AbstractOrdersEventHandlerUnitTest.java
+++ b/axon/src/test/java/com/baeldung/axon/querymodel/AbstractOrdersEventHandlerUnitTest.java
@@ -14,10 +14,13 @@ import com.baeldung.axon.coreapi.queries.OrderUpdatesQuery;
import com.baeldung.axon.coreapi.queries.TotalProductsShippedQuery;
import org.axonframework.queryhandling.QueryUpdateEmitter;
import org.junit.jupiter.api.*;
+import reactor.core.publisher.Flux;
+import reactor.test.StepVerifier;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
+import java.util.function.Consumer;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
@@ -68,6 +71,26 @@ public abstract class AbstractOrdersEventHandlerUnitTest {
assertEquals(orderTwo, order_2);
}
+ @Test
+ void givenTwoOrdersPlacedOfWhichOneNotShipped_whenFindAllOrderedProductsQueryStreaming_thenCorrectOrdersAreReturned() {
+ resetWithTwoOrders();
+ final Consumer orderVerifier = order -> {
+ if (order.getOrderId().equals(orderOne.getOrderId())) {
+ assertEquals(orderOne, order);
+ } else if (order.getOrderId().equals(orderTwo.getOrderId())) {
+ assertEquals(orderTwo, order);
+ } else {
+ throw new RuntimeException("Would expect either order one or order two");
+ }
+ };
+
+ StepVerifier.create(Flux.from(handler.handleStreaming(new FindAllOrderedProductsQuery())))
+ .assertNext(orderVerifier)
+ .assertNext(orderVerifier)
+ .expectComplete()
+ .verify();
+ }
+
@Test
void givenNoOrdersPlaced_whenTotalProductsShippedQuery_thenZeroReturned() {
assertEquals(0, handler.handle(new TotalProductsShippedQuery(PRODUCT_ID_1)));
diff --git a/axon/src/test/java/com/baeldung/axon/querymodel/OrderQueryServiceIntegrationTest.java b/axon/src/test/java/com/baeldung/axon/querymodel/OrderQueryServiceIntegrationTest.java
index 60808b2271..dfb4881fdc 100644
--- a/axon/src/test/java/com/baeldung/axon/querymodel/OrderQueryServiceIntegrationTest.java
+++ b/axon/src/test/java/com/baeldung/axon/querymodel/OrderQueryServiceIntegrationTest.java
@@ -6,6 +6,7 @@ import com.baeldung.axon.coreapi.events.OrderShippedEvent;
import com.baeldung.axon.coreapi.events.ProductAddedEvent;
import com.baeldung.axon.coreapi.events.ProductCountDecrementedEvent;
import com.baeldung.axon.coreapi.events.ProductCountIncrementedEvent;
+import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
import com.baeldung.axon.coreapi.queries.Order;
import org.axonframework.eventhandling.gateway.EventGateway;
@@ -13,6 +14,7 @@ import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
+import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
import java.util.Collections;
@@ -60,6 +62,15 @@ class OrderQueryServiceIntegrationTest {
.isEmpty());
}
+ @Test
+ void givenOrderCreatedEventSend_whenCallingAllOrdersStreaming_thenOneOrderIsReturned() {
+ Flux result = queryService.allOrdersStreaming();
+ StepVerifier.create(result)
+ .assertNext(order -> assertEquals(orderId, order.getOrderId()))
+ .expectComplete()
+ .verify();
+ }
+
@Test
void givenThreeDeluxeChairsShipped_whenCallingAllShippedChairs_then234PlusTreeIsReturned() {
Order order = new Order(orderId);
diff --git a/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/listandset/ListAndSetUnitTest.java b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/listandset/ListAndSetUnitTest.java
new file mode 100644
index 0000000000..c57c1f96b8
--- /dev/null
+++ b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/listandset/ListAndSetUnitTest.java
@@ -0,0 +1,43 @@
+package com.baeldung.listandset;
+
+import org.junit.Test;
+import org.junit.Assert;
+import java.util.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ListAndSetUnitTest {
+
+ @Test
+ public void givenList_whenDuplicates_thenAllowed(){
+ List integerList = new ArrayList<>();
+ integerList.add(2);
+ integerList.add(3);
+ integerList.add(4);
+ integerList.add(4);
+ assertEquals(integerList.size(), 4);
+ }
+
+ @Test
+ public void givenSet_whenDuplicates_thenNotAllowed(){
+ Set integerSet = new HashSet<>();
+ integerSet.add(2);
+ integerSet.add(3);
+ integerSet.add(4);
+ integerSet.add(4);
+ assertEquals(integerSet.size(), 3);
+ }
+
+ @Test
+ public void givenSet_whenOrdering_thenMayBeAllowed(){
+ Set set1 = new LinkedHashSet<>();
+ set1.add(2);
+ set1.add(3);
+ set1.add(4);
+ Set set2 = new LinkedHashSet<>();
+ set2.add(2);
+ set2.add(3);
+ set2.add(4);
+ Assert.assertArrayEquals(set1.toArray(), set2.toArray());
+ }
+}
diff --git a/core-java-modules/core-java-collections-list-4/pom.xml b/core-java-modules/core-java-collections-list-4/pom.xml
index 773f8c105b..49b3f849d4 100644
--- a/core-java-modules/core-java-collections-list-4/pom.xml
+++ b/core-java-modules/core-java-collections-list-4/pom.xml
@@ -56,6 +56,12 @@
${assertj.version}
test
+
+ org.springframework
+ spring-core
+ ${spring.version}
+ test
+
@@ -80,6 +86,7 @@
3.22.0
17
17
+ 5.3.22
\ No newline at end of file
diff --git a/core-java-modules/core-java-collections-list-4/src/test/java/com/baeldung/list/tostring/ListToStringUnitTest.java b/core-java-modules/core-java-collections-list-4/src/test/java/com/baeldung/list/tostring/ListToStringUnitTest.java
new file mode 100644
index 0000000000..479ccaf92f
--- /dev/null
+++ b/core-java-modules/core-java-collections-list-4/src/test/java/com/baeldung/list/tostring/ListToStringUnitTest.java
@@ -0,0 +1,132 @@
+package com.baeldung.list.tostring;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+
+import org.junit.jupiter.api.Test;
+
+class ListToStringUnitTest {
+
+ @Test
+ void givenAListOfString_whenUsingJava8_thenConvertToStringByUsingString() {
+
+ List arraysAsList = Arrays.asList("ONE", "TWO", "THREE");
+
+ String commaSeparatedString = String.join(",", arraysAsList);
+
+ assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE");
+ }
+
+ @Test
+ void givenAListOfString_whenUsingJava8_thenConvertToStringByUsingStringJoiner() {
+
+ List arraysAsList = Arrays.asList("ONE", "TWO", "THREE");
+
+ StringJoiner stringJoiner = new StringJoiner(",");
+ arraysAsList.stream()
+ .forEach(v -> stringJoiner.add(v));
+ String commaSeparatedString = stringJoiner.toString();
+
+ assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE");
+
+ StringJoiner stringJoinerWithDelimiterPrefixSuffix = new StringJoiner(",", "[", "]");
+ arraysAsList.stream()
+ .forEach(v -> stringJoinerWithDelimiterPrefixSuffix.add(v));
+ String commaSeparatedStringWithDelimiterPrefixSuffix = stringJoinerWithDelimiterPrefixSuffix.toString();
+
+ assertThat(commaSeparatedStringWithDelimiterPrefixSuffix).isEqualTo("[ONE,TWO,THREE]");
+ }
+
+ @Test
+ void givenAListOfString_whenUsingJava8_thenConvertToStringByUsingCollectors() {
+
+ List arraysAsList = Arrays.asList("ONE", "TWO", "THREE");
+
+ String commaSeparatedUsingCollect = arraysAsList.stream()
+ .collect(Collectors.joining(","));
+
+ assertThat(commaSeparatedUsingCollect).isEqualTo("ONE,TWO,THREE");
+
+ String commaSeparatedObjectToString = arraysAsList.stream()
+ .map(Object::toString)
+ .collect(Collectors.joining(","));
+
+ assertThat(commaSeparatedObjectToString).isEqualTo("ONE,TWO,THREE");
+
+ String commaSeparatedStringValueOf = arraysAsList.stream()
+ .map(String::valueOf)
+ .collect(Collectors.joining(","));
+
+ assertThat(commaSeparatedStringValueOf).isEqualTo("ONE,TWO,THREE");
+
+ String commaSeparatedStringValueOfWithDelimiterPrefixSuffix = arraysAsList.stream()
+ .map(String::valueOf)
+ .collect(Collectors.joining(",", "[", "]"));
+
+ assertThat(commaSeparatedStringValueOfWithDelimiterPrefixSuffix).isEqualTo("[ONE,TWO,THREE]");
+
+ String commaSeparatedUsingReduce = arraysAsList.stream()
+ .reduce((x, y) -> x + "," + y)
+ .get();
+
+ assertThat(commaSeparatedUsingReduce).isEqualTo("ONE,TWO,THREE");
+ }
+
+ @Test
+ void givenAListOfString_whenUsingApacheCommonsLang_thenConvertToStringByUsingStringUtils() {
+
+ List arraysAsList = Arrays.asList("ONE", "TWO", "THREE");
+
+ String commaSeparatedString = org.apache.commons.lang3.StringUtils.join(arraysAsList, ",");
+
+ assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE");
+
+ String commaSeparatedStringIndex = org.apache.commons.lang3.StringUtils.join(arraysAsList.toArray(), ",", 0, 3);
+
+ assertThat(commaSeparatedStringIndex).isEqualTo("ONE,TWO,THREE");
+ }
+
+ @Test
+ void givenAListOfString_whenUsingSpringCore_thenConvertToStringByUsingStringUtils() {
+
+ List arraysAsList = Arrays.asList("ONE", "TWO", "THREE");
+
+ String collectionToCommaDelimitedString = org.springframework.util.StringUtils.collectionToCommaDelimitedString(arraysAsList);
+
+ assertThat(collectionToCommaDelimitedString).isEqualTo("ONE,TWO,THREE");
+
+ String collectionToDelimitedString = org.springframework.util.StringUtils.collectionToDelimitedString(arraysAsList, ",");
+
+ assertThat(collectionToDelimitedString).isEqualTo("ONE,TWO,THREE");
+ }
+
+ @Test
+ void givenAListOfString_whenUsingGoogleGuava_thenConvertToStringByUsingJoiner() {
+
+ List arraysAsList = Arrays.asList("ONE", "TWO", "THREE");
+
+ String commaSeparatedString = com.google.common.base.Joiner.on(",")
+ .join(arraysAsList);
+
+ assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE");
+
+ List arraysAsListWithNull = Arrays.asList("ONE", null, "TWO", null, "THREE");
+
+ String commaSeparatedStringSkipNulls = com.google.common.base.Joiner.on(",")
+ .skipNulls()
+ .join(arraysAsListWithNull);
+
+ assertThat(commaSeparatedStringSkipNulls).isEqualTo("ONE,TWO,THREE");
+
+ String commaSeparatedStringUseForNull = com.google.common.base.Joiner.on(",")
+ .useForNull(" ")
+ .join(arraysAsListWithNull);
+
+ assertThat(commaSeparatedStringUseForNull).isEqualTo("ONE, ,TWO, ,THREE");
+ }
+
+}
diff --git a/core-java-modules/core-java-date-operations-3/README.md b/core-java-modules/core-java-date-operations-3/README.md
index 7c3146d32b..cc84760560 100644
--- a/core-java-modules/core-java-date-operations-3/README.md
+++ b/core-java-modules/core-java-date-operations-3/README.md
@@ -3,4 +3,5 @@ This module contains articles about date operations in Java.
### Relevant Articles:
+- [Create Date From Unix Timestamp in Java](https://www.baeldung.com/java-date-unix-timestamp)
- [[<-- Prev]](/core-java-modules/core-java-date-operations-2)
diff --git a/core-java-modules/core-java-function/README.md b/core-java-modules/core-java-function/README.md
index 7fe6044835..eb27aea153 100644
--- a/core-java-modules/core-java-function/README.md
+++ b/core-java-modules/core-java-function/README.md
@@ -5,3 +5,4 @@
### Relevant Articles:
- [Java 8 Predicate Chain](https://www.baeldung.com/java-predicate-chain)
- [Use Cases for Static Methods in Java](https://www.baeldung.com/java-static-methods-use-cases)
+- [TriFunction Interface in Java](https://www.baeldung.com/java-trifunction)
diff --git a/core-java-modules/core-java-io-4/README.md b/core-java-modules/core-java-io-4/README.md
index 27a71cb2a2..fdf9ebcb77 100644
--- a/core-java-modules/core-java-io-4/README.md
+++ b/core-java-modules/core-java-io-4/README.md
@@ -11,4 +11,5 @@ This module contains articles about core Java input and output (IO)
- [Read User Input Until a Condition is Met](https://www.baeldung.com/java-read-input-until-condition)
- [Java Scanner.skip method with examples](https://www.baeldung.com/java-scanner-skip)
- [Generate the MD5 Checksum for a File in Java](https://www.baeldung.com/java-md5-checksum-file)
+- [Getting the Filename From a String Containing an Absolute File Path](https://www.baeldung.com/java-filename-full-path)
- [[<-- Prev]](/core-java-modules/core-java-io-3)
diff --git a/core-java-modules/core-java-io-apis-2/README.md b/core-java-modules/core-java-io-apis-2/README.md
index 93307f8294..f3d72fe8b5 100644
--- a/core-java-modules/core-java-io-apis-2/README.md
+++ b/core-java-modules/core-java-io-apis-2/README.md
@@ -4,3 +4,4 @@ This module contains articles about core Java input/output(IO) APIs.
### Relevant Articles:
- [Constructing a Relative Path From Two Absolute Paths in Java](https://www.baeldung.com/java-relative-path-absolute)
+- [Java Scanner Taking a Character Input](https://www.baeldung.com/java-scanner-character-input)
diff --git a/core-java-modules/core-java-lang-math-3/README.md b/core-java-modules/core-java-lang-math-3/README.md
index 48af72a036..3c1e1d79ee 100644
--- a/core-java-modules/core-java-lang-math-3/README.md
+++ b/core-java-modules/core-java-lang-math-3/README.md
@@ -7,4 +7,5 @@
- [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string)
- [Swap Two Variables in Java](https://www.baeldung.com/java-swap-two-variables)
- [Java Program to Find the Roots of a Quadratic Equation](https://www.baeldung.com/roots-quadratic-equation/)
+- [Create a BMI Calculator in Java](https://www.baeldung.com/java-body-mass-index-calculator)
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)
diff --git a/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/portscanner/PortScanner.java b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/portscanner/PortScanner.java
new file mode 100644
index 0000000000..9220472cad
--- /dev/null
+++ b/core-java-modules/core-java-networking-3/src/main/java/com/baeldung/portscanner/PortScanner.java
@@ -0,0 +1,51 @@
+package com.baeldung.portscanner;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class PortScanner {
+ private static final int poolSize = 10;
+ private static final int timeOut = 200;
+
+ public void runPortScan(String ip, int nbrPortMaxToScan) throws IOException, RuntimeException {
+ ConcurrentLinkedQueue openPorts = new ConcurrentLinkedQueue<>();
+ ExecutorService executorService = Executors.newFixedThreadPool(poolSize);
+ AtomicInteger port = new AtomicInteger(0);
+ while (port.get() < nbrPortMaxToScan) {
+ final int currentPort = port.getAndIncrement();
+ executorService.submit(() -> {
+ try {
+ Socket socket = new Socket();
+ socket.connect(new InetSocketAddress(ip, currentPort), timeOut);
+ socket.close();
+ openPorts.add(currentPort);
+ System.out.println(ip + " ,port open: " + currentPort);
+ } catch (IOException e) {
+ System.err.println(e);
+ }
+ });
+ }
+ executorService.shutdown();
+ try {
+ executorService.awaitTermination(10, TimeUnit.MINUTES);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+
+ List openPortList = new ArrayList<>();
+ System.out.println("openPortsQueue: " + openPorts.size());
+ while (!openPorts.isEmpty()) {
+ openPortList.add(openPorts.poll());
+ }
+
+ openPortList.forEach(p -> System.out.println("port " + p + " is open"));
+ }
+}
diff --git a/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/portScanner/PortScannerUnitTest.java b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/portScanner/PortScannerUnitTest.java
new file mode 100644
index 0000000000..2fc4ff7550
--- /dev/null
+++ b/core-java-modules/core-java-networking-3/src/test/java/com/baeldung/portScanner/PortScannerUnitTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.portScanner;
+
+import com.baeldung.portscanner.PortScanner;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+
+class PortScannerUnitTest {
+
+ private static final int nbrPortMax = 1000; // Max is 65535, number of available ports
+ private static final String ip = "127.0.0.1";
+ PortScanner portScanner = new PortScanner();
+
+ @Test public void when_Run_then_lunchPortScan() throws IOException, RuntimeException {
+ portScanner.runPortScan(ip, nbrPortMax);
+ }
+}
diff --git a/core-java-modules/core-java-numbers-5/README.md b/core-java-modules/core-java-numbers-5/README.md
index 19e155b525..714e808239 100644
--- a/core-java-modules/core-java-numbers-5/README.md
+++ b/core-java-modules/core-java-numbers-5/README.md
@@ -5,3 +5,4 @@
- [Armstrong Numbers in Java](https://www.baeldung.com/java-armstrong-numbers)
- [List All Factors of a Number in Java](https://www.baeldung.com/java-list-factors-integer)
- [Make Division of Two Integers Result in a Float](https://www.baeldung.com/java-integer-division-float-result)
+- [Creating Random Numbers With No Duplicates in Java](https://www.baeldung.com/java-unique-random-numbers)
diff --git a/core-java-modules/core-java-string-operations-5/README.md b/core-java-modules/core-java-string-operations-5/README.md
index 7917fcf77b..71c28aac30 100644
--- a/core-java-modules/core-java-string-operations-5/README.md
+++ b/core-java-modules/core-java-string-operations-5/README.md
@@ -2,3 +2,4 @@
### Relevant Articles:
- [Compare Characters in Java](https://www.baeldung.com/java-compare-characters)
+- [String Concatenation in Java](https://www.baeldung.com/java-string-concatenation)
diff --git a/core-java-modules/core-java-uuid/README.md b/core-java-modules/core-java-uuid/README.md
index 836552d798..0a77c36acd 100644
--- a/core-java-modules/core-java-uuid/README.md
+++ b/core-java-modules/core-java-uuid/README.md
@@ -3,3 +3,4 @@
### Relevant Articles:
- [Generating Alphanumeric UUID String in Java](https://www.baeldung.com/java-generate-alphanumeric-uuid)
- [Guide to UUID in Java](http://www.baeldung.com/java-uuid)
+- [Validate UUID String in Java](https://www.baeldung.com/java-validate-uuid-string)
diff --git a/docker-modules/docker-compose/README.md b/docker-modules/docker-compose/README.md
index 7c3347332e..5ab629e54f 100644
--- a/docker-modules/docker-compose/README.md
+++ b/docker-modules/docker-compose/README.md
@@ -6,4 +6,5 @@
- [Difference Between links and depends_on in Docker Compose](https://www.baeldung.com/ops/docker-compose-links-depends-on)
- [Mounting Multiple Volumes on a Docker Container](https://www.baeldung.com/ops/docker-mounting-multiple-volumes)
- [Rebuild Docker Container in Docker Compose](https://www.baeldung.com/rebuild-docker-container-compose/)
+- [Assign Static IP to Docker Container and Docker-Compose](https://www.baeldung.com/ops/docker-assign-static-ip-container)
diff --git a/docker-modules/docker-images/README.md b/docker-modules/docker-images/README.md
index 3b2ae6b56f..7813ec4279 100644
--- a/docker-modules/docker-images/README.md
+++ b/docker-modules/docker-images/README.md
@@ -3,3 +3,5 @@
- [Pushing a Docker Image to a Private Repository](https://www.baeldung.com/ops/docker-push-image-to-private-repository)
- [How to Include Files Outside of Docker’s Build Context](https://www.baeldung.com/ops/docker-include-files-outside-build-context)
- [Adding a Comment in a Dockerfile](https://www.baeldung.com/ops/docker-dockerfile-comments/)
+- [Updating PATH Environment Variable in Dockerfile](https://www.baeldung.com/ops/dockerfile-path-environment-variable)
+- [Keep Subdirectory Structure in Dockerfile Copy](https://www.baeldung.com/ops/dockerfile-copy-same-subdirectory-structure)
diff --git a/docker-modules/docker-java-jar/README.md b/docker-modules/docker-java-jar/README.md
index 73c8249e58..9b5aa501ee 100644
--- a/docker-modules/docker-java-jar/README.md
+++ b/docker-modules/docker-java-jar/README.md
@@ -2,3 +2,4 @@
### Relevant Articles:
- [Dockerizing a Java Application](https://www.baeldung.com/java-dockerize-app)
+- [Debugging an Application Running in Docker With IntelliJ IDEA](https://www.baeldung.com/docker-debug-app-with-intellij)
diff --git a/jmeter/src/main/resources/JMeter - Latency Vs Load Time.jmx b/jmeter/src/main/resources/JMeter - Latency Vs Load Time.jmx
new file mode 100644
index 0000000000..6cf79f230e
--- /dev/null
+++ b/jmeter/src/main/resources/JMeter - Latency Vs Load Time.jmx
@@ -0,0 +1,88 @@
+
+
+
+
+
+ false
+ true
+ false
+
+
+
+
+
+
+
+ continue
+
+ false
+ 1
+
+ 1
+ 1
+ false
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+ http://localhost:3000
+ GET
+ true
+ false
+ true
+ false
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+
+ true
+ true
+ true
+
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml
index c268aeacc5..66548e45cb 100644
--- a/parent-spring-5/pom.xml
+++ b/parent-spring-5/pom.xml
@@ -24,8 +24,8 @@
- 5.3.22
- 5.6.0
+ 5.3.23
+ 5.7.3
1.5.10.RELEASE
diff --git a/patterns-modules/design-patterns-architectural/README.md b/patterns-modules/design-patterns-architectural/README.md
index bb11eea5e1..0f0e75afeb 100644
--- a/patterns-modules/design-patterns-architectural/README.md
+++ b/patterns-modules/design-patterns-architectural/README.md
@@ -4,3 +4,4 @@
- [DAO vs Repository Patterns](https://www.baeldung.com/java-dao-vs-repository)
- [Difference Between MVC and MVP Patterns](https://www.baeldung.com/mvc-vs-mvp-pattern)
- [The DTO Pattern (Data Transfer Object)](https://www.baeldung.com/java-dto-pattern)
+- [SEDA With Spring Integration and Apache Camel](https://www.baeldung.com/spring-apache-camel-seda-integration)
diff --git a/persistence-modules/core-java-persistence-2/README.md b/persistence-modules/core-java-persistence-2/README.md
index 4bc7d8b663..56cb2fb1d0 100644
--- a/persistence-modules/core-java-persistence-2/README.md
+++ b/persistence-modules/core-java-persistence-2/README.md
@@ -8,3 +8,4 @@
- [JDBC Connection Status](https://www.baeldung.com/jdbc-connection-status)
- [Get the Number of Rows in a ResultSet](https://www.baeldung.com/java-resultset-number-of-rows)
- [Converting a JDBC ResultSet to JSON in Java](https://www.baeldung.com/java-jdbc-convert-resultset-to-json)
+- [Guide to MicroStream](https://www.baeldung.com/microstream-intro)
diff --git a/persistence-modules/java-mongodb-3/src/main/java/com/baeldung/mongo/insert/InsertArrayOperation.java b/persistence-modules/java-mongodb-3/src/main/java/com/baeldung/mongo/insert/InsertArrayOperation.java
new file mode 100644
index 0000000000..e073a1ec88
--- /dev/null
+++ b/persistence-modules/java-mongodb-3/src/main/java/com/baeldung/mongo/insert/InsertArrayOperation.java
@@ -0,0 +1,157 @@
+package com.baeldung.mongo.insert;
+
+import com.mongodb.*;
+import com.mongodb.client.FindIterable;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoCursor;
+import com.mongodb.client.MongoDatabase;
+import org.bson.Document;
+import org.bson.conversions.Bson;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.mongodb.client.model.Filters.eq;
+import static com.mongodb.client.model.Filters.in;
+
+public class InsertArrayOperation {
+
+ private static MongoClient mongoClient;
+ private static MongoDatabase database;
+ private static MongoCollection collection;
+ private static DB db;
+ private static DBCollection dbCollection;
+ private static String collectionName;
+ private static String databaseName;
+
+ public static void setUp() {
+ if (mongoClient == null) {
+ mongoClient = new MongoClient("localhost", 27017);
+
+ databaseName = "baeldung";
+ collectionName = "student";
+
+ database = mongoClient.getDatabase(databaseName);
+ collection = database.getCollection(collectionName);
+
+ db = mongoClient.getDB(databaseName);
+ dbCollection = db.getCollection(collectionName);
+ }
+ }
+
+ public static void insertSingleBsonDocumentWithStringArray() {
+ BasicDBList coursesList = new BasicDBList();
+ coursesList.add("Chemistry");
+ coursesList.add("Science");
+
+ DBObject student = new BasicDBObject().append("studentId", "STUD1")
+ .append("name", "Jim")
+ .append("age", 13)
+ .append("courses", coursesList);
+
+ dbCollection.insert(student);
+
+ Bson filter = eq("studentId", "STUD1");
+ FindIterable documents = collection.find(filter);
+
+ MongoCursor cursor = documents.iterator();
+ while (cursor.hasNext()) {
+ System.out.println(cursor.next());
+ }
+ }
+
+ public static void insertSingleDocumentWithStringArray() {
+ List coursesList = new ArrayList<>();
+ coursesList.add("Science");
+ coursesList.add("Geography");
+
+ Document student = new Document().append("studentId", "STUD2")
+ .append("name", "Sam")
+ .append("age", 13)
+ .append("courses", coursesList);
+
+ collection.insertOne(student);
+
+ Bson filter = eq("studentId", "STUD2");
+ FindIterable documents = collection.find(filter);
+
+ MongoCursor cursor = documents.iterator();
+ while (cursor.hasNext()) {
+ System.out.println(cursor.next());
+ }
+ }
+
+ public static void insertMultipleDocumentsWithStringArray() {
+ List coursesList1 = new ArrayList<>();
+ coursesList1.add("Chemistry");
+ coursesList1.add("Geography");
+
+ Document student1 = new Document().append("studentId", "STUD3")
+ .append("name", "Sarah")
+ .append("age", 12)
+ .append("courses", coursesList1);
+
+ List coursesList2 = new ArrayList<>();
+ coursesList2.add("Maths");
+ coursesList2.add("History");
+
+ Document student2 = new Document().append("studentId", "STUD4")
+ .append("name", "Tom")
+ .append("age", 13)
+ .append("courses", coursesList2);
+
+ List students = new ArrayList<>();
+ students.add(student1);
+ students.add(student2);
+
+ collection.insertMany(students);
+
+ Bson filter = in("studentId", "STUD3", "STUD4");
+ FindIterable documents = collection.find(filter);
+
+ MongoCursor cursor = documents.iterator();
+ while (cursor.hasNext()) {
+ System.out.println(cursor.next());
+ }
+ }
+
+ public static void insertSingleDocumentWithObjectArray() {
+ Document course1 = new Document().append("name", "C1")
+ .append("points", 5);
+
+ Document course2 = new Document().append("name", "C2")
+ .append("points", 7);
+
+ List coursesList = new ArrayList<>();
+ coursesList.add(course1);
+ coursesList.add(course2);
+
+ Document student = new Document().append("studentId", "STUD5")
+ .append("name", "Avin")
+ .append("age", 13)
+ .append("courses", coursesList);
+
+ collection.insertOne(student);
+
+ Bson filter = eq("studentId", "STUD5");
+ FindIterable documents = collection.find(filter);
+
+ MongoCursor cursor = documents.iterator();
+ while (cursor.hasNext()) {
+ System.out.println(cursor.next());
+ }
+ }
+
+ public static void main(String args[]) {
+
+ setUp();
+
+ insertSingleBsonDocumentWithStringArray();
+
+ insertSingleDocumentWithStringArray();
+
+ insertMultipleDocumentsWithStringArray();
+
+ insertSingleDocumentWithObjectArray();
+ }
+}
diff --git a/persistence-modules/java-mongodb-3/src/test/java/com/baeldung/mongo/insert/InsertArrayOperationLiveTest.java b/persistence-modules/java-mongodb-3/src/test/java/com/baeldung/mongo/insert/InsertArrayOperationLiveTest.java
new file mode 100644
index 0000000000..a844a003f0
--- /dev/null
+++ b/persistence-modules/java-mongodb-3/src/test/java/com/baeldung/mongo/insert/InsertArrayOperationLiveTest.java
@@ -0,0 +1,150 @@
+package com.baeldung.mongo.insert;
+
+import com.mongodb.*;
+import com.mongodb.client.FindIterable;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoCursor;
+import com.mongodb.client.MongoDatabase;
+import org.bson.Document;
+import org.bson.conversions.Bson;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.mongodb.client.model.Filters.eq;
+import static com.mongodb.client.model.Filters.in;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class InsertArrayOperationLiveTest {
+
+ private static MongoClient mongoClient;
+ private static MongoDatabase database;
+ private static MongoCollection collection;
+ private static DB db;
+ private static DBCollection dbCollection;
+
+ @BeforeClass
+ public static void setUp() {
+ if (mongoClient == null) {
+ mongoClient = new MongoClient("localhost", 27017);
+
+ database = mongoClient.getDatabase("baeldung");
+ collection = database.getCollection("student");
+
+ db = mongoClient.getDB("baeldung");
+ dbCollection = db.getCollection("student");
+
+ collection.drop();
+ }
+ }
+
+ @Test
+ public void givenSingleStudentObjectWithStringArray_whenInsertingDBObject_thenCheckingForDocument() {
+ BasicDBList coursesList = new BasicDBList();
+ coursesList.add("Chemistry");
+ coursesList.add("Science");
+
+ DBObject student = new BasicDBObject().append("studentId", "STUD1")
+ .append("name", "Jim")
+ .append("age", 13)
+ .append("courses", coursesList);
+
+ dbCollection.insert(student);
+
+ Bson filter = eq("studentId", "STUD2");
+ FindIterable documents = collection.find(filter);
+
+ MongoCursor cursor = documents.iterator();
+
+ assertNotNull(cursor);
+ assertTrue(cursor.hasNext());
+ }
+
+ @Test
+ public void givenSingleStudentObjectWithStringArray_whenInsertingDocument_thenCheckingForDocument() {
+ List coursesList = new ArrayList<>();
+ coursesList.add("Science");
+ coursesList.add("Geography");
+
+ Document student = new Document().append("studentId", "STUD2")
+ .append("name", "Sam")
+ .append("age", 13)
+ .append("courses", coursesList);
+
+ collection.insertOne(student);
+
+ Bson filter = eq("studentId", "STUD2");
+ FindIterable documents = collection.find(filter);
+
+ MongoCursor cursor = documents.iterator();
+
+ assertNotNull(cursor);
+ assertTrue(cursor.hasNext());
+ }
+
+ @Test
+ public void givenMultipleStudentObjectsWithStringArray_whenInsertingDocuments_thenCheckingForDocuments() {
+ List coursesList1 = new ArrayList<>();
+ coursesList1.add("Chemistry");
+ coursesList1.add("Geography");
+
+ Document student1 = new Document().append("studentId", "STUD3")
+ .append("name", "Sarah")
+ .append("age", 12)
+ .append("courses", coursesList1);
+
+ List coursesList2 = new ArrayList<>();
+ coursesList2.add("Maths");
+ coursesList2.add("History");
+
+ Document student2 = new Document().append("studentId", "STUD4")
+ .append("name", "Tom")
+ .append("age", 13)
+ .append("courses", coursesList2);
+
+ List students = new ArrayList<>();
+ students.add(student1);
+ students.add(student2);
+
+ collection.insertMany(students);
+
+ Bson filter = in("studentId", "STUD3", "STUD4");
+ FindIterable documents = collection.find(filter);
+
+ MongoCursor cursor = documents.iterator();
+
+ assertNotNull(cursor);
+ assertTrue(cursor.hasNext());
+ }
+
+ @Test
+ public void givenSingleStudentObjectWithObjectArray_whenInsertingDocument_thenCheckingForDocument() {
+ Document course1 = new Document().append("name", "C1")
+ .append("points", 5);
+
+ Document course2 = new Document().append("name", "C2")
+ .append("points", 7);
+
+ List coursesList = new ArrayList<>();
+ coursesList.add(course1);
+ coursesList.add(course2);
+
+ Document student = new Document().append("studentId", "STUD5")
+ .append("name", "Sam")
+ .append("age", 13)
+ .append("courses", coursesList);
+
+ collection.insertOne(student);
+
+ Bson filter = eq("studentId", "STUD5");
+ FindIterable documents = collection.find(filter);
+
+ MongoCursor cursor = documents.iterator();
+
+ assertNotNull(cursor);
+ assertTrue(cursor.hasNext());
+ }
+}
diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationIntegrationTest.java b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationLiveTest.java
similarity index 91%
rename from spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationIntegrationTest.java
rename to spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationLiveTest.java
index e0bbef1c7f..5fc8597252 100644
--- a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationIntegrationTest.java
+++ b/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationLiveTest.java
@@ -20,7 +20,8 @@ import static org.mockito.Mockito.when;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SpringBoot.class)
-public class KeycloakConfigurationIntegrationTest {
+//requires running Keycloak server and realm setup as shown in https://www.baeldung.com/spring-boot-keycloak
+public class KeycloakConfigurationLiveTest {
@Spy
private KeycloakSecurityContextClientRequestInterceptor factory;
diff --git a/spring-boot-modules/spring-boot-libraries-2/pom.xml b/spring-boot-modules/spring-boot-libraries-2/pom.xml
index 79c090dde5..de4e879089 100644
--- a/spring-boot-modules/spring-boot-libraries-2/pom.xml
+++ b/spring-boot-modules/spring-boot-libraries-2/pom.xml
@@ -133,6 +133,7 @@
2.4.5
0.2.1
2.9.2
+ com.baeldung.openapi.OpenApiApplication
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/kong/StockApp.java b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/kong/StockApp.java
index f901592938..b46d7ca9b0 100644
--- a/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/kong/StockApp.java
+++ b/spring-boot-modules/spring-boot-libraries-2/src/main/java/com/baeldung/kong/StockApp.java
@@ -1,9 +1,12 @@
package com.baeldung.kong;
+import org.jobrunr.autoconfigure.JobRunrAutoConfiguration;
import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
+@EnableAutoConfiguration(exclude = { JobRunrAutoConfiguration.class})
public class StockApp {
public static void main(String[] args) {
diff --git a/spring-boot-modules/spring-boot-mvc-2/README.md b/spring-boot-modules/spring-boot-mvc-2/README.md
index 30e6d71a30..1d89726b71 100644
--- a/spring-boot-modules/spring-boot-mvc-2/README.md
+++ b/spring-boot-modules/spring-boot-mvc-2/README.md
@@ -5,8 +5,6 @@ This module contains articles about Spring Web MVC in Spring Boot projects.
### Relevant Articles:
- [Functional Controllers in Spring MVC](https://www.baeldung.com/spring-mvc-functional-controllers)
-- [Specify an Array of Strings as Body Parameters in Swagger](https://www.baeldung.com/swagger-body-array-of-strings)
-- [Swagger @ApiParam vs @ApiModelProperty](https://www.baeldung.com/swagger-apiparam-vs-apimodelproperty)
- [Testing REST with multiple MIME types](https://www.baeldung.com/testing-rest-api-with-multiple-media-types)
- [Testing Web APIs with Postman Collections](https://www.baeldung.com/postman-testing-collections)
- [Spring Boot Consuming and Producing JSON](https://www.baeldung.com/spring-boot-json)
diff --git a/spring-boot-modules/spring-boot-mvc-2/pom.xml b/spring-boot-modules/spring-boot-mvc-2/pom.xml
index f303171df8..bcc0cb68a0 100644
--- a/spring-boot-modules/spring-boot-mvc-2/pom.xml
+++ b/spring-boot-modules/spring-boot-mvc-2/pom.xml
@@ -28,22 +28,6 @@
spring-boot-devtools
true
-
-
- io.springfox
- springfox-swagger2
- ${spring.fox.version}
-
-
- io.springfox
- springfox-swagger-ui
- ${spring.fox.version}
-
-
- io.springfox
- springfox-spring-webmvc
- ${spring.fox.version}
-
org.apache.commons
commons-lang3
@@ -90,8 +74,7 @@
3.0.0
- com.baeldung.swagger2boot.SpringBootSwaggerApplication
-
+ com.baeldung.springbootmvc.SpringBootMvcFnApplication
1.4.11.1
diff --git a/spring-boot-modules/spring-boot-swagger-2/README.md b/spring-boot-modules/spring-boot-swagger-2/README.md
index e607b56299..242f3d3385 100644
--- a/spring-boot-modules/spring-boot-swagger-2/README.md
+++ b/spring-boot-modules/spring-boot-swagger-2/README.md
@@ -1,3 +1,5 @@
### Relevant Articles:
- [Swagger: Specify Two Responses with the Same Response Code](https://www.baeldung.com/swagger-two-responses-one-response-code)
+- [Specify an Array of Strings as Body Parameters in Swagger](https://www.baeldung.com/swagger-body-array-of-strings)
+- [Swagger @ApiParam vs @ApiModelProperty](https://www.baeldung.com/swagger-apiparam-vs-apimodelproperty)
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-swagger-2/pom.xml b/spring-boot-modules/spring-boot-swagger-2/pom.xml
index 055d8ce3eb..a054773731 100644
--- a/spring-boot-modules/spring-boot-swagger-2/pom.xml
+++ b/spring-boot-modules/spring-boot-swagger-2/pom.xml
@@ -39,6 +39,16 @@
javax.validation
validation-api
+
+ io.springfox
+ springfox-swagger2
+ ${springfox.version}
+
+
+ io.springfox
+ springfox-spring-webmvc
+ ${springfox.version}
+
@@ -63,6 +73,13 @@
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ ${start-class}
+
+
@@ -70,6 +87,8 @@
3.0.0
3.0.34
1.6.10
+ 3.1.1
+ com.baeldung.tworesponses.Application
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/SpringBootSwaggerApplication.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/SpringBootSwaggerApplication.java
similarity index 89%
rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/SpringBootSwaggerApplication.java
rename to spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/SpringBootSwaggerApplication.java
index 0f68f75d16..e166d28e7c 100644
--- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/SpringBootSwaggerApplication.java
+++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/SpringBootSwaggerApplication.java
@@ -1,4 +1,4 @@
-package com.baeldung.swagger2boot;
+package com.baeldung.swagger2bootmvc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/config/Swagger2Config.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/config/Swagger2Config.java
similarity index 88%
rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/config/Swagger2Config.java
rename to spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/config/Swagger2Config.java
index 6f3557d597..d4a7774510 100644
--- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/config/Swagger2Config.java
+++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/config/Swagger2Config.java
@@ -1,7 +1,8 @@
-package com.baeldung.swagger2boot.config;
+package com.baeldung.swagger2bootmvc.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
@@ -9,10 +10,12 @@ import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
-import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
@Configuration
-@EnableSwagger2WebMvc
+@EnableWebMvc
+@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket api() {
diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/FooController.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/FooController.java
similarity index 91%
rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/FooController.java
rename to spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/FooController.java
index ac6d99c40c..5edf610154 100644
--- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/FooController.java
+++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/FooController.java
@@ -1,4 +1,4 @@
-package com.baeldung.swagger2boot.controller;
+package com.baeldung.swagger2bootmvc.controller;
import static org.apache.commons.lang3.RandomStringUtils.randomNumeric;
@@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
-import com.baeldung.swagger2boot.model.Foo;
+import com.baeldung.swagger2bootmvc.model.Foo;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/UserController.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/UserController.java
similarity index 68%
rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/UserController.java
rename to spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/UserController.java
index d8102a8407..fa879f3bea 100644
--- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/controller/UserController.java
+++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/UserController.java
@@ -1,19 +1,17 @@
-package com.baeldung.swagger2boot.controller;
+package com.baeldung.swagger2bootmvc.controller;
-import com.baeldung.swagger2boot.model.Foo;
-import com.baeldung.swagger2boot.model.User;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
-import javax.validation.Valid;
-import javax.websocket.server.PathParam;
+import com.baeldung.swagger2bootmvc.model.User;
-import static org.apache.commons.lang3.RandomStringUtils.randomNumeric;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
@Controller
public class UserController {
diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/Foo.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/Foo.java
similarity index 94%
rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/Foo.java
rename to spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/Foo.java
index e48c2016c0..f3fe56e07d 100644
--- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/Foo.java
+++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/Foo.java
@@ -1,4 +1,4 @@
-package com.baeldung.swagger2boot.model;
+package com.baeldung.swagger2bootmvc.model;
import java.util.List;
diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/User.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/User.java
similarity index 92%
rename from spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/User.java
rename to spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/User.java
index d4a6479f4e..b4ec55f564 100644
--- a/spring-boot-modules/spring-boot-mvc-2/src/main/java/com/baeldung/swagger2boot/model/User.java
+++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/User.java
@@ -1,4 +1,4 @@
-package com.baeldung.swagger2boot.model;
+package com.baeldung.swagger2bootmvc.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
diff --git a/spring-boot-modules/spring-boot-mvc-2/src/main/resources/swagger-description.yml b/spring-boot-modules/spring-boot-swagger-2/src/main/resources/swagger-description.yml
similarity index 100%
rename from spring-boot-modules/spring-boot-mvc-2/src/main/resources/swagger-description.yml
rename to spring-boot-modules/spring-boot-swagger-2/src/main/resources/swagger-description.yml
diff --git a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClient.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClient.java
index b842b948d7..2cef3d4238 100644
--- a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClient.java
+++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClient.java
@@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
-@FeignClient(name = "product-client", url = "http://localhost:8081/product/", configuration = FeignConfig.class)
+@FeignClient(name = "product-client", url = "http://localhost:8084/product/", configuration = FeignConfig.class)
public interface ProductClient {
@RequestMapping(value = "{id}", method = RequestMethod.GET)
diff --git a/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClientUnitTest.java b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClientUnitTest.java
index 392cb19050..4dda2bbe15 100644
--- a/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClientUnitTest.java
+++ b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/client/ProductClientUnitTest.java
@@ -27,9 +27,10 @@ public class ProductClientUnitTest {
@Before
public void startWireMockServer() {
- wireMockServer = new WireMockServer(8081);
- configureFor("localhost", 8081);
+ wireMockServer = new WireMockServer(8084);
+ configureFor("localhost", 8084);
wireMockServer.start();
+
}
@After
diff --git a/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductControllerUnitTest.java b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductControllerUnitTest.java
index 269cd2d2d6..bfc0c3d281 100644
--- a/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductControllerUnitTest.java
+++ b/spring-cloud-modules/spring-cloud-openfeign/src/test/java/com/baeldung/cloud/openfeign/defaulterrorhandling/controller/ProductControllerUnitTest.java
@@ -20,7 +20,6 @@ import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
@RunWith(SpringRunner.class)
@WebMvcTest(ProductController.class)
@ImportAutoConfiguration({FeignAutoConfiguration.class, TestControllerAdvice.class})
@@ -37,8 +36,8 @@ public class ProductControllerUnitTest {
@Before
public void startWireMockServer() {
- wireMockServer = new WireMockServer(8081);
- configureFor("localhost", 8081);
+ wireMockServer = new WireMockServer(8084);
+ configureFor("localhost", 8084);
wireMockServer.start();
}
diff --git a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/relationships/SpringSecurityConfig.java b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/relationships/SpringSecurityConfig.java
index 3d4182f423..bce0e21e7a 100644
--- a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/relationships/SpringSecurityConfig.java
+++ b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/relationships/SpringSecurityConfig.java
@@ -7,15 +7,18 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
+import org.springframework.security.provisioning.JdbcUserDetailsManager;
+import org.springframework.security.provisioning.UserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.context.WebApplicationContext;
import com.baeldung.relationships.security.AuthenticationSuccessHandlerImpl;
@@ -24,7 +27,7 @@ import com.baeldung.relationships.security.CustomUserDetailsService;
@Configuration
@EnableWebSecurity
@ComponentScan("com.baeldung.security")
-public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
+public class SpringSecurityConfig {
@Autowired
private WebApplicationContext applicationContext;
@@ -42,24 +45,28 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
userDetailsService = applicationContext.getBean(CustomUserDetailsService.class);
}
- @Override
- protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
- auth.userDetailsService(userDetailsService)
+ @Bean
+ public UserDetailsManager users(HttpSecurity http) throws Exception {
+ AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManagerBuilder.class)
+ .userDetailsService(userDetailsService)
.passwordEncoder(encoder())
.and()
.authenticationProvider(authenticationProvider())
- .jdbcAuthentication()
- .dataSource(dataSource);
+ .build();
+
+ JdbcUserDetailsManager jdbcUserDetailsManager = new JdbcUserDetailsManager(dataSource);
+ jdbcUserDetailsManager.setAuthenticationManager(authenticationManager);
+ return jdbcUserDetailsManager;
}
- @Override
- public void configure(WebSecurity web) {
- web.ignoring()
+ @Bean
+ public WebSecurityCustomizer webSecurityCustomizer() {
+ return (web) -> web.ignoring()
.antMatchers("/resources/**");
}
- @Override
- protected void configure(final HttpSecurity http) throws Exception {
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login")
.permitAll()
@@ -70,6 +77,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
.and()
.csrf()
.disable();
+ return http.build();
}
@Bean
diff --git a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/custom/config/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/custom/config/SecurityConfig.java
index 6bf04120ab..ea882f7ba9 100644
--- a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/custom/config/SecurityConfig.java
+++ b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/custom/config/SecurityConfig.java
@@ -4,16 +4,16 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
-public class SecurityConfig extends WebSecurityConfigurerAdapter {
+public class SecurityConfig {
- @Override
- protected void configure(final HttpSecurity http) throws Exception {
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.authorizeRequests()
@@ -22,6 +22,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.and()
.formLogin()
.permitAll();
+ return http.build();
}
@Bean
diff --git a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/ip/config/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/ip/config/SecurityConfig.java
index 71c7bcccc6..6b6fa8c6a3 100644
--- a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/ip/config/SecurityConfig.java
+++ b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/ip/config/SecurityConfig.java
@@ -1,33 +1,50 @@
package com.baeldung.roles.ip.config;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
-public class SecurityConfig extends WebSecurityConfigurerAdapter {
+public class SecurityConfig {
@Autowired
private CustomIpAuthenticationProvider authenticationProvider;
- @Override
- protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
- auth.inMemoryAuthentication().withUser("john").password("{noop}123").authorities("ROLE_USER");
- // auth.authenticationProvider(authenticationProvider);
+ @Bean
+ public InMemoryUserDetailsManager userDetailsService(HttpSecurity http) throws Exception {
+ UserDetails user = User.withUsername("john")
+ .password("{noop}123")
+ .authorities("ROLE_USER")
+ .build();
+ http.getSharedObject(AuthenticationManagerBuilder.class)
+ .authenticationProvider(authenticationProvider)
+ .build();
+ return new InMemoryUserDetailsManager(user);
}
- @Override
- protected void configure(final HttpSecurity http) throws Exception {
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
- .antMatchers("/login").permitAll()
-// .antMatchers("/foos/**").hasIpAddress("11.11.11.11")
- .antMatchers("/foos/**").access("isAuthenticated() and hasIpAddress('11.11.11.11')")
- .anyRequest().authenticated()
- .and().formLogin().permitAll()
- .and().csrf().disable();
+ .antMatchers("/login")
+ .permitAll()
+ .antMatchers("/foos/**")
+ .access("isAuthenticated() and hasIpAddress('11.11.11.11')")
+ .anyRequest()
+ .authenticated()
+ .and()
+ .formLogin()
+ .permitAll()
+ .and()
+ .csrf()
+ .disable();
+ return http.build();
}
}
\ No newline at end of file
diff --git a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/rolesauthorities/config/SecurityConfig.java b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/rolesauthorities/config/SecurityConfig.java
index 9b7ccfd25b..d464b82d1c 100644
--- a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/rolesauthorities/config/SecurityConfig.java
+++ b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/rolesauthorities/config/SecurityConfig.java
@@ -1,26 +1,28 @@
package com.baeldung.roles.rolesauthorities.config;
-import com.baeldung.roles.rolesauthorities.CustomAuthenticationProvider;
-import com.baeldung.roles.rolesauthorities.persistence.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
+import com.baeldung.roles.rolesauthorities.CustomAuthenticationProvider;
+import com.baeldung.roles.rolesauthorities.persistence.UserRepository;
+
@Configuration
@ComponentScan(basePackages = {"com.baeldung.rolesauthorities"})
@EnableWebSecurity
-public class SecurityConfig extends WebSecurityConfigurerAdapter {
+public class SecurityConfig {
@Autowired
private UserRepository userRepository;
@@ -31,39 +33,43 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private LogoutSuccessHandler myLogoutSuccessHandler;
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.authenticationProvider(authProvider());
+ @Bean
+ public AuthenticationManager authManager(HttpSecurity http) throws Exception {
+ return http.getSharedObject(AuthenticationManagerBuilder.class)
+ .authenticationProvider(authProvider())
+ .build();
}
- @Override
- public void configure(WebSecurity web) throws Exception {
- web.ignoring()
+ @Bean
+ public WebSecurityCustomizer webSecurityCustomizer() {
+ return (web) -> web.ignoring()
.antMatchers("/resources/**");
}
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
-
- http
- .csrf().disable()
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ http.csrf()
+ .disable()
.authorizeRequests()
- .antMatchers("/login*", "/logout*", "/protectedbynothing*", "/home*").permitAll()
- .antMatchers("/protectedbyrole").hasRole("USER")
- .antMatchers("/protectedbyauthority").hasAuthority("READ_PRIVILEGE")
- .and()
+ .antMatchers("/login*", "/logout*", "/protectedbynothing*", "/home*")
+ .permitAll()
+ .antMatchers("/protectedbyrole")
+ .hasRole("USER")
+ .antMatchers("/protectedbyauthority")
+ .hasAuthority("READ_PRIVILEGE")
+ .and()
.formLogin()
- .loginPage("/login")
- .failureUrl("/login?error=true")
- .permitAll()
- .and()
+ .loginPage("/login")
+ .failureUrl("/login?error=true")
+ .permitAll()
+ .and()
.logout()
- .logoutSuccessHandler(myLogoutSuccessHandler)
- .invalidateHttpSession(false)
- .logoutSuccessUrl("/logout.html?logSucc=true")
- .deleteCookies("JSESSIONID")
- .permitAll();
+ .logoutSuccessHandler(myLogoutSuccessHandler)
+ .invalidateHttpSession(false)
+ .logoutSuccessUrl("/logout.html?logSucc=true")
+ .deleteCookies("JSESSIONID")
+ .permitAll();
+ return http.build();
}
@Bean
diff --git a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/voter/WebSecurityConfig.java b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/voter/WebSecurityConfig.java
index 5141e1af7c..146853c18b 100644
--- a/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/voter/WebSecurityConfig.java
+++ b/spring-security-modules/spring-security-web-boot-1/src/main/java/com/baeldung/roles/voter/WebSecurityConfig.java
@@ -1,5 +1,8 @@
package com.baeldung.roles.voter;
+import java.util.Arrays;
+import java.util.List;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -11,17 +14,14 @@ import org.springframework.security.access.vote.UnanimousBased;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.expression.WebExpressionVoter;
-import java.util.Arrays;
-import java.util.List;
-
@Configuration
@EnableWebSecurity
-public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+public class WebSecurityConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
@@ -36,22 +36,23 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.roles("ADMIN");
}
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http
- .csrf()
- .disable()
- .authorizeRequests()
- .anyRequest()
- .authenticated()
- .accessDecisionManager(accessDecisionManager())
- .and()
- .formLogin()
- .permitAll()
- .and()
- .logout()
- .permitAll()
- .deleteCookies("JSESSIONID").logoutSuccessUrl("/login");
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ http.csrf()
+ .disable()
+ .authorizeRequests()
+ .anyRequest()
+ .authenticated()
+ .accessDecisionManager(accessDecisionManager())
+ .and()
+ .formLogin()
+ .permitAll()
+ .and()
+ .logout()
+ .permitAll()
+ .deleteCookies("JSESSIONID")
+ .logoutSuccessUrl("/login");
+ return http.build();
}
@Bean
diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/filter/CustomWebSecurityConfigurerAdapter.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/filter/CustomWebSecurityConfigurerAdapter.java
index fb597e46c8..5714b2fb3e 100644
--- a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/filter/CustomWebSecurityConfigurerAdapter.java
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/filter/CustomWebSecurityConfigurerAdapter.java
@@ -1,20 +1,21 @@
package com.baeldung.filter;
-import com.baeldung.security.RestAuthenticationEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
+import com.baeldung.security.RestAuthenticationEntryPoint;
+
@Configuration
@EnableWebSecurity
-public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
+public class CustomWebSecurityConfigurerAdapter {
@Autowired private RestAuthenticationEntryPoint authenticationEntryPoint;
@@ -27,19 +28,18 @@ public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAda
.authorities("ROLE_USER");
}
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http
- .authorizeRequests()
- .antMatchers("/securityNone")
- .permitAll()
- .anyRequest()
- .authenticated()
- .and()
- .httpBasic()
- .authenticationEntryPoint(authenticationEntryPoint);
-
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ http.authorizeRequests()
+ .antMatchers("/securityNone")
+ .permitAll()
+ .anyRequest()
+ .authenticated()
+ .and()
+ .httpBasic()
+ .authenticationEntryPoint(authenticationEntryPoint);
http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class);
+ return http.build();
}
@Bean
diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java
index 4b32a1126e..839fa15734 100644
--- a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java
@@ -1,27 +1,30 @@
package com.baeldung.inmemory;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
@Configuration
-public class InMemoryAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
+public class InMemoryAuthWebSecurityConfigurer {
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
- auth.inMemoryAuthentication()
- .passwordEncoder(encoder)
- .withUser("spring")
- .password(encoder.encode("secret"))
- .roles("USER");
+ @Bean
+ public InMemoryUserDetailsManager userDetailsService() {
+ PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
+ UserDetails user = User.withUsername("spring")
+ .password(encoder.encode("secret"))
+ .roles("USER")
+ .build();
+ return new InMemoryUserDetailsManager(user);
}
- @Override
- protected void configure(HttpSecurity http) throws Exception {
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/private/**")
.authenticated()
@@ -29,6 +32,7 @@ public class InMemoryAuthWebSecurityConfigurer extends WebSecurityConfigurerAdap
.permitAll()
.and()
.httpBasic();
+ return http.build();
}
}
diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryNoOpAuthWebSecurityConfigurer.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryNoOpAuthWebSecurityConfigurer.java
index 4b6494f666..72d3ef79d7 100644
--- a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryNoOpAuthWebSecurityConfigurer.java
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/inmemory/InMemoryNoOpAuthWebSecurityConfigurer.java
@@ -1,23 +1,26 @@
package com.baeldung.inmemory;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
//@Configuration
-public class InMemoryNoOpAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
+public class InMemoryNoOpAuthWebSecurityConfigurer {
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.inMemoryAuthentication()
- .withUser("spring")
+ @Bean
+ public InMemoryUserDetailsManager userDetailsService() {
+ UserDetails user = User.withUsername("spring")
.password("{noop}secret")
- .roles("USER");
+ .roles("USER")
+ .build();
+ return new InMemoryUserDetailsManager(user);
}
- @Override
- protected void configure(HttpSecurity http) throws Exception {
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/private/**")
.authenticated()
@@ -25,5 +28,6 @@ public class InMemoryNoOpAuthWebSecurityConfigurer extends WebSecurityConfigurer
.permitAll()
.and()
.httpBasic();
+ return http.build();
}
}
diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java
index 59a2ae1dc2..a1c6e1ee76 100644
--- a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java
@@ -1,9 +1,14 @@
package com.baeldung.passwordstorage;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@@ -14,18 +19,16 @@ import org.springframework.security.crypto.password.StandardPasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
@Configuration
-public class PasswordStorageWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
+public class PasswordStorageWebSecurityConfigurer {
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.eraseCredentials(false) // 4
- .userDetailsService(getUserDefaultDetailsService())
- .passwordEncoder(passwordEncoder());
+ @Bean
+ public AuthenticationManager authManager(HttpSecurity http) throws Exception {
+ AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
+ authenticationManagerBuilder.eraseCredentials(false)
+ .userDetailsService(getUserDefaultDetailsService())
+ .passwordEncoder(passwordEncoder());
+ return authenticationManagerBuilder.build();
}
@Bean
diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/postman/basic/PostmanBasicAuthConfig.java b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/postman/basic/PostmanBasicAuthConfig.java
index a6311972c2..7a8848dcae 100644
--- a/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/postman/basic/PostmanBasicAuthConfig.java
+++ b/spring-security-modules/spring-security-web-rest-basic-auth/src/main/java/com/baeldung/postman/basic/PostmanBasicAuthConfig.java
@@ -1,16 +1,17 @@
package com.baeldung.postman.basic;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.SecurityFilterChain;
@Configuration
-public class PostmanBasicAuthConfig extends WebSecurityConfigurerAdapter {
+public class PostmanBasicAuthConfig {
- @Override
- protected void configure(HttpSecurity http) throws Exception {
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.authorizeRequests()
@@ -18,6 +19,7 @@ public class PostmanBasicAuthConfig extends WebSecurityConfigurerAdapter {
.authenticated()
.and()
.httpBasic();
+ return http.build();
}
@Autowired
diff --git a/spring-security-modules/spring-security-web-rest/src/main/java/com/baeldung/security/SecurityJavaConfig.java b/spring-security-modules/spring-security-web-rest/src/main/java/com/baeldung/security/SecurityJavaConfig.java
index 7f0b20ea34..0a79151f89 100644
--- a/spring-security-modules/spring-security-web-rest/src/main/java/com/baeldung/security/SecurityJavaConfig.java
+++ b/spring-security-modules/spring-security-web-rest/src/main/java/com/baeldung/security/SecurityJavaConfig.java
@@ -1,28 +1,31 @@
package com.baeldung.security;
-import com.baeldung.security.web.MySavedRequestAwareAuthenticationSuccessHandler;
-import com.baeldung.security.web.RestAuthenticationEntryPoint;
-import com.baeldung.web.error.CustomAccessDeniedHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.task.DelegatingSecurityContextAsyncTaskExecutor;
+import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
+import com.baeldung.security.web.MySavedRequestAwareAuthenticationSuccessHandler;
+import com.baeldung.security.web.RestAuthenticationEntryPoint;
+import com.baeldung.web.error.CustomAccessDeniedHandler;
+
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ComponentScan("com.baeldung.security")
-public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
+public class SecurityJavaConfig {
@Autowired
private CustomAccessDeniedHandler accessDeniedHandler;
@@ -35,17 +38,23 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
private SimpleUrlAuthenticationFailureHandler myFailureHandler = new SimpleUrlAuthenticationFailureHandler();
- @Override
- protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
- auth.inMemoryAuthentication()
- .withUser("admin").password(encoder().encode("adminPass")).roles("ADMIN")
- .and()
- .withUser("user").password(encoder().encode("userPass")).roles("USER");
+ @Bean
+ public InMemoryUserDetailsManager userDetailsService() {
+ UserDetails admin = User.withUsername("admin")
+ .password(encoder().encode("adminPass"))
+ .roles("ADMIN")
+ .build();
+ UserDetails user = User.withUsername("user")
+ .password(encoder().encode("userPass"))
+ .roles("USER")
+ .build();
+ return new InMemoryUserDetailsManager(admin, user);
}
- @Override
- protected void configure(final HttpSecurity http) throws Exception {
- http.csrf().disable()
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ http.csrf()
+ .disable()
.authorizeRequests()
.and()
.exceptionHandling()
@@ -53,11 +62,16 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
.authenticationEntryPoint(restAuthenticationEntryPoint)
.and()
.authorizeRequests()
- .antMatchers("/api/csrfAttacker*").permitAll()
- .antMatchers("/api/customer/**").permitAll()
- .antMatchers("/api/foos/**").authenticated()
- .antMatchers("/api/async/**").permitAll()
- .antMatchers("/api/admin/**").hasRole("ADMIN")
+ .antMatchers("/api/csrfAttacker*")
+ .permitAll()
+ .antMatchers("/api/customer/**")
+ .permitAll()
+ .antMatchers("/api/foos/**")
+ .authenticated()
+ .antMatchers("/api/async/**")
+ .permitAll()
+ .antMatchers("/api/admin/**")
+ .hasRole("ADMIN")
.and()
.formLogin()
.successHandler(mySuccessHandler)
@@ -66,6 +80,7 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
.httpBasic()
.and()
.logout();
+ return http.build();
}
@Bean
diff --git a/spring-web-modules/spring-mvc-basics-5/README.md b/spring-web-modules/spring-mvc-basics-5/README.md
index dfd6522b0f..e7f39c8ea2 100644
--- a/spring-web-modules/spring-mvc-basics-5/README.md
+++ b/spring-web-modules/spring-mvc-basics-5/README.md
@@ -14,4 +14,5 @@ The "REST With Spring" Classes: https://bit.ly/restwithspring
- [Spring @RequestParam Annotation](https://www.baeldung.com/spring-request-param)
- [Spring @RequestParam vs @PathVariable Annotations](https://www.baeldung.com/spring-requestparam-vs-pathvariable)
- [@RequestMapping Value in Properties File](https://www.baeldung.com/spring-requestmapping-properties-file)
+- [Map a JSON POST to Multiple Spring MVC Parameters](https://www.baeldung.com/spring-mvc-json-param-mapping)
- More articles: [[<-- prev]](../spring-mvc-basics-4)