Merge branch 'eugenp:master' into master

This commit is contained in:
Wynn Teo 2024-02-19 16:15:29 +08:00 committed by GitHub
commit 1b620ed663
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
90 changed files with 1851 additions and 354 deletions

View File

@ -0,0 +1,43 @@
package com.baeldung.algorithms.primeundernumber;
import java.util.Arrays;
public class LargestPrimeFinder {
public static int findByBruteForce(int n) {
for (int i = n - 1; i >= 2; i--) {
if (isPrime(i)) {
return i;
}
}
return -1; // Return -1 if no prime number is found
}
public static boolean isPrime(int number) {
for (int i = 2; i <= Math.sqrt(number); i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
public static int findBySieveOfEratosthenes(int n) {
boolean[] isPrime = new boolean[n];
Arrays.fill(isPrime, true);
for (int p = 2; p*p < n; p++) {
if (isPrime[p]) {
for (int i = p * p; i < n; i += p) {
isPrime[i] = false;
}
}
}
for (int i = n - 1; i >= 2; i--) {
if (isPrime[i]) {
return i;
}
}
return -1;
}
}

View File

@ -0,0 +1,32 @@
package com.baeldung.algorithms.primeundernumber;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class LargestPrimeFinderUnitTest {
@Test
public void givenNormalCases_whenFindPrime_ThenFoundResult() {
assertEquals(7, LargestPrimeFinder.findByBruteForce(10));
assertEquals(97, LargestPrimeFinder.findByBruteForce(100));
assertEquals(7, LargestPrimeFinder.findBySieveOfEratosthenes(10));
assertEquals(97, LargestPrimeFinder.findBySieveOfEratosthenes(100));
}
@Test
public void givenEdgeCases_whenFindPrime_ThenNotFoundResult() {
assertEquals(-1, LargestPrimeFinder.findByBruteForce(0));
assertEquals(-1, LargestPrimeFinder.findByBruteForce(1));
assertEquals(-1, LargestPrimeFinder.findByBruteForce(2));
assertEquals(-1, LargestPrimeFinder.findBySieveOfEratosthenes(0));
assertEquals(-1, LargestPrimeFinder.findBySieveOfEratosthenes(1));
assertEquals(-1, LargestPrimeFinder.findBySieveOfEratosthenes(2));
}
@Test
public void givenLargeInput_whenFindPrime_ThenFoundResult() {
assertEquals(99991, LargestPrimeFinder.findByBruteForce(100000));
assertEquals(99991, LargestPrimeFinder.findBySieveOfEratosthenes(100000));
}
}

View File

@ -13,3 +13,4 @@ This module contains articles about searching algorithms.
- [Range Search Algorithm in Java](https://www.baeldung.com/java-range-search) - [Range Search Algorithm in Java](https://www.baeldung.com/java-range-search)
- [Fast Pattern Matching of Strings Using Suffix Tree in Java](https://www.baeldung.com/java-pattern-matching-suffix-tree) - [Fast Pattern Matching of Strings Using Suffix Tree in Java](https://www.baeldung.com/java-pattern-matching-suffix-tree)
- [Find the Kth Smallest Element in Two Sorted Arrays in Java](https://www.baeldung.com/java-kth-smallest-element-in-sorted-arrays) - [Find the Kth Smallest Element in Two Sorted Arrays in Java](https://www.baeldung.com/java-kth-smallest-element-in-sorted-arrays)
- [Find the First Non-repeating Element of a List](https://www.baeldung.com/java-list-find-first-non-repeating-element)

View File

@ -19,10 +19,29 @@
<artifactId>validation-api</artifactId> <artifactId>validation-api</artifactId>
<version>${javax.validation.validation-api.version}</version> <version>${javax.validation.validation-api.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-junit5</artifactId>
<version>${camel.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-main</artifactId>
<version>${camel.version}</version>
</dependency>
</dependencies> </dependencies>
<properties> <properties>
<javax.validation.validation-api.version>2.0.1.Final</javax.validation.validation-api.version> <javax.validation.validation-api.version>2.0.1.Final</javax.validation.validation-api.version>
<camel.version>4.3.0</camel.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,29 @@
package com.baeldung.dynamicrouter;
import org.apache.camel.ExchangeProperties;
import java.util.Map;
public class DynamicRouterBean {
public String route(String body, @ExchangeProperties Map<String, Object> properties) {
int invoked = (int) properties.getOrDefault("invoked", 0) + 1;
properties.put("invoked", invoked);
if (invoked == 1) {
switch (body.toLowerCase()) {
case "mock":
return "mock:dynamicRouter";
case "direct":
return "mock:directDynamicRouter";
case "seda":
return "mock:sedaDynamicRouter";
case "file":
return "mock:fileDynamicRouter";
default:
break;
}
}
return null;
}
}

View File

@ -0,0 +1,13 @@
package com.baeldung.dynamicrouter;
import org.apache.camel.builder.RouteBuilder;
public class DynamicRouterRoute extends RouteBuilder {
@Override
public void configure() {
from("direct:dynamicRouter").dynamicRouter(method(DynamicRouterBean.class, "route"));
}
}

View File

@ -0,0 +1,61 @@
package dynamicrouter;
import com.baeldung.dynamicrouter.DynamicRouterRoute;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit5.CamelTestSupport;
import org.junit.jupiter.api.Test;
public class DynamicRouterRouteUnitTest extends CamelTestSupport {
@Override
protected RoutesBuilder createRouteBuilder() {
return new DynamicRouterRoute();
}
@Test
void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndMockAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException {
MockEndpoint mockDynamicEndpoint = getMockEndpoint("mock:dynamicRouter");
mockDynamicEndpoint.expectedMessageCount(1);
template.send("direct:dynamicRouter", exchange -> exchange.getIn()
.setBody("mock"));
MockEndpoint.assertIsSatisfied(context);
}
@Test
void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndDirectAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException {
MockEndpoint mockDynamicEndpoint = context.getEndpoint("mock:directDynamicRouter", MockEndpoint.class);
mockDynamicEndpoint.expectedMessageCount(1);
template.send("direct:dynamicRouter", exchange -> exchange.getIn()
.setBody("direct"));
MockEndpoint.assertIsSatisfied(context);
}
@Test
void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndSedaAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException {
MockEndpoint mockDynamicEndpoint = context.getEndpoint("mock:sedaDynamicRouter", MockEndpoint.class);
mockDynamicEndpoint.expectedMessageCount(1);
template.send("direct:dynamicRouter", exchange -> exchange.getIn()
.setBody("seda"));
MockEndpoint.assertIsSatisfied(context);
}
@Test
void givenDynamicRouter_whenMockEndpointExpectedMessageCountOneAndBookAsMessageBody_thenMessageSentToDynamicRouter() throws InterruptedException {
MockEndpoint mockDynamicEndpoint = getMockEndpoint("mock:fileDynamicRouter");
mockDynamicEndpoint.expectedMessageCount(1);
template.send("direct:dynamicRouter", exchange -> exchange.getIn()
.setBody("file"));
MockEndpoint.assertIsSatisfied(context);
}
}

View File

@ -1,2 +1,4 @@
## Relevant Articles ## Relevant Articles
- [Find the Middle Element of an Array in Java](https://www.baeldung.com/java-array-middle-item) - [Find the Middle Element of an Array in Java](https://www.baeldung.com/java-array-middle-item)
- [Find the Equilibrium Indexes of an Array in Java](https://www.baeldung.com/java-equilibrium-index-array)
- [Moves Zeros to the End of an Array in Java](https://www.baeldung.com/java-array-sort-move-zeros-end)

View File

@ -7,4 +7,5 @@
- [Limiting the Max Size of a HashMap in Java](https://www.baeldung.com/java-hashmap-size-bound) - [Limiting the Max Size of a HashMap in Java](https://www.baeldung.com/java-hashmap-size-bound)
- [How to Sort LinkedHashMap by Values in Java](https://www.baeldung.com/java-sort-linkedhashmap-using-values) - [How to Sort LinkedHashMap by Values in Java](https://www.baeldung.com/java-sort-linkedhashmap-using-values)
- [How to Increment a Map Value in Java](https://www.baeldung.com/java-increment-map-value) - [How to Increment a Map Value in Java](https://www.baeldung.com/java-increment-map-value)
- [Collect Stream of entrySet() to a LinkedHashMap](https://www.baeldung.com/java-linkedhashmap-entryset-stream)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-6) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-6)

View File

@ -8,3 +8,4 @@
- [How to Check if All Runnables Are Done](https://www.baeldung.com/java-runnables-check-status) - [How to Check if All Runnables Are Done](https://www.baeldung.com/java-runnables-check-status)
- [Parallelize for Loop in Java](https://www.baeldung.com/java-for-loop-parallel) - [Parallelize for Loop in Java](https://www.baeldung.com/java-for-loop-parallel)
- [How to Effectively Unit Test CompletableFuture](https://www.baeldung.com/java-completablefuture-unit-test) - [How to Effectively Unit Test CompletableFuture](https://www.baeldung.com/java-completablefuture-unit-test)
- [How to Collect All Results and Handle Exceptions With CompletableFuture in a Loop](https://www.baeldung.com/java-completablefuture-collect-results-handle-exceptions)

View File

@ -0,0 +1,90 @@
package com.baeldung.concurrent.completablefuture;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
public class CombiningCompletableFuturesUnitTest {
private final Logger logger = mock(Logger.class);
private static Stream<Arguments> clientData() {
return Stream.of(
Arguments.of(List.of("Good Resource"), 1, 0),
Arguments.of(List.of("Bad Resource"), 0, 1),
Arguments.of(List.of("Good Resource", "Bad Resource"), 1, 1),
Arguments.of(List.of("Good Resource", "Bad Resource", "Good Resource", "Bad Resource", "Good Resource"), 3, 2)
);
}
@ParameterizedTest
@MethodSource("clientData")
public void givenMicroserviceClient_whenMultipleCreateResource_thenCombineResults(List<String> inputs, int successCount, int errorCount) {
MicroserviceClient mockMicroservice = mock(MicroserviceClient.class);
// Return an identifier of 123 on "Good Resource"
when(mockMicroservice.createResource("Good Resource"))
.thenReturn(CompletableFuture.completedFuture(123L));
// Throw an exception on "Bad Resource"
when(mockMicroservice.createResource("Bad Resource"))
.thenReturn(CompletableFuture.failedFuture(new IllegalArgumentException("Bad Resource")));
// Given a list of CompletableFutures from our microservice calls...
List<CompletableFuture<Long>> clientCalls = new ArrayList<>();
for (String resource : inputs) {
clientCalls.add(mockMicroservice.createResource(resource));
}
// When all CompletableFutures are completed (exceptionally or otherwise)...
Map<Boolean, List<Long>> resultsByValidity = clientCalls.stream()
.map(this::handleFuture)
.collect(Collectors.partitioningBy(resourceId -> resourceId != -1L));
// Then the returned resource identifiers should match what is expected...
List<Long> validResults = resultsByValidity.getOrDefault(true, List.of());
assertThat(validResults.size()).isEqualTo(successCount);
// And the logger mock should be called once for each exception with the expected error message
List<Long> invalidResults = resultsByValidity.getOrDefault(false, List.of());
assertThat(invalidResults.size()).isEqualTo(errorCount);
verify(logger, times(errorCount))
.error(eq("Encountered error: java.lang.IllegalArgumentException: Bad Resource"));
}
/**
* Completes the given CompletableFuture, handling any exceptions that are thrown.
* @param future the CompletableFuture to complete.
* @return the resource identifier (-1 if the request failed).
*/
private Long handleFuture(CompletableFuture<Long> future) {
return future
.exceptionally(this::handleError)
.join();
}
private Long handleError(Throwable throwable) {
logger.error("Encountered error: " + throwable);
return -1L;
}
interface MicroserviceClient {
CompletableFuture<Long> createResource(String resourceName);
}
interface Logger {
void error(String message);
}
}

View File

@ -4,3 +4,4 @@ This module contains articles about date operations in Java.
### Relevant Articles: ### Relevant Articles:
- [Calculate Number of Weekdays Between Two Dates in Java](https://www.baeldung.com/java-count-weekdays-between-two-dates) - [Calculate Number of Weekdays Between Two Dates in Java](https://www.baeldung.com/java-count-weekdays-between-two-dates)
- [Convert Long to Date in Java](https://www.baeldung.com/java-long-date-conversion) - [Convert Long to Date in Java](https://www.baeldung.com/java-long-date-conversion)
- [Convert Date to Unix Timestamp in Java](https://www.baeldung.com/java-convert-date-unix-timestamp)

View File

@ -4,7 +4,6 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 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> <modelVersion>4.0.0</modelVersion>
<artifactId>core-java-datetime-conversion-2</artifactId> <artifactId>core-java-datetime-conversion-2</artifactId>
<version>${project.parent.version}</version>
<name>core-java-datetime-conversion-2</name> <name>core-java-datetime-conversion-2</name>
<packaging>jar</packaging> <packaging>jar</packaging>

View File

@ -4,7 +4,6 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 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> <modelVersion>4.0.0</modelVersion>
<artifactId>core-java-datetime-conversion</artifactId> <artifactId>core-java-datetime-conversion</artifactId>
<version>${project.parent.version}</version>
<name>core-java-datetime-conversion</name> <name>core-java-datetime-conversion</name>
<packaging>jar</packaging> <packaging>jar</packaging>

View File

@ -0,0 +1,72 @@
package com.baeldung.math.rodcutting;
import java.util.Arrays;
public class RodCuttingProblem {
static int maxRevenueG;
public static int usingRecursion(int[] prices, int n) {
if (n <= 0) {
return 0;
}
int maxRevenue = Integer.MIN_VALUE;
for (int i = 1; i <= n; i++) {
maxRevenue = Math.max(maxRevenue, prices[i - 1] + usingRecursion(prices, n - i));
}
return maxRevenue;
}
public static int usingMemoizedRecursion(int[] prices, int n) {
int[] memo = new int[n + 1];
Arrays.fill(memo, -1);
return memoizedHelper(prices, n, memo);
}
private static int memoizedHelper(int[] prices, int n, int[] memo) {
if (n <= 0) {
return 0;
}
if (memo[n] != -1) {
return memo[n];
}
int maxRevenue = Integer.MIN_VALUE;
for (int i = 1; i <= n; i++) {
maxRevenue = Math.max(maxRevenue, prices[i - 1] + memoizedHelper(prices, n - i, memo));
}
memo[n] = maxRevenue;
return maxRevenue;
}
public static int usingDynamicProgramming(int[] prices, int n) {
int[] dp = new int[n + 1];
for (int i = 1; i <= n; i++) {
int maxRevenue = Integer.MIN_VALUE;
for (int j = 1; j <= i; j++) {
maxRevenue = Math.max(maxRevenue, prices[j - 1] + dp[i - j]);
}
dp[i] = maxRevenue;
}
return dp[n];
}
public static int usingUnboundedKnapsack(int[] prices, int n) {
int[] dp = new int[n + 1];
for (int i = 1; i <= n; i++) {
for (int j = 0; j < prices.length; j++) {
if (j + 1 <= i) {
dp[i] = Math.max(dp[i], dp[i - (j + 1)] + prices[j]);
}
}
}
return dp[n];
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.math.rodcutting;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
public class RodCuttingProblemUnitTest {
@Test
void givenARod_whenUsingRecursion_thenFindMaxRevenue() {
int[] prices = {1, 5, 8, 9};
int rodLength = 4;
int maxRevenue = RodCuttingProblem.usingRecursion(prices, rodLength);
assertEquals(10, maxRevenue);
}
@Test
void givenARod_whenUsingMemoizedRecursion_thenFindMaxRevenue() {
int[] prices = {1, 5, 8, 9};
int rodLength = 4;
int maxRevenue = RodCuttingProblem.usingMemoizedRecursion(prices, rodLength);
assertEquals(10, maxRevenue);
}
@Test
void givenARod_whenUsingDynamicProgramming_thenFindMaxRevenue() {
int[] prices = {1, 5, 8, 9};
int rodLength = 4;
int maxRevenue = RodCuttingProblem.usingDynamicProgramming(prices, rodLength);
assertEquals(10, maxRevenue);
}
@Test
void givenARod_whenUsingGreedy_thenFindMaxRevenue() {
int[] prices = {1, 5, 8, 9};
int rodLength = 4;
int maxRevenue = RodCuttingProblem.usingUnboundedKnapsack(prices, rodLength);
assertEquals(10, maxRevenue);
}
}

View File

@ -11,3 +11,4 @@ This module contains articles about Object-oriented programming (OOP) patterns i
- [Should We Create an Interface for Only One Implementation?](https://www.baeldung.com/java-interface-single-implementation) - [Should We Create an Interface for Only One Implementation?](https://www.baeldung.com/java-interface-single-implementation)
- [How to Deep Copy an ArrayList in Java](https://www.baeldung.com/java-arraylist-deep-copy) - [How to Deep Copy an ArrayList in Java](https://www.baeldung.com/java-arraylist-deep-copy)
- [Stateless Object in Java](https://www.baeldung.com/java-stateless-object) - [Stateless Object in Java](https://www.baeldung.com/java-stateless-object)
- [Mutable vs. Immutable Objects in Java](https://www.baeldung.com/java-mutable-vs-immutable-objects)

View File

@ -11,3 +11,4 @@ This module contains articles about Java operators
- [Alternatives for instanceof Operator in Java](https://www.baeldung.com/java-instanceof-alternatives) - [Alternatives for instanceof Operator in Java](https://www.baeldung.com/java-instanceof-alternatives)
- [What Does “––>” Mean in Java?](https://www.baeldung.com/java-minus-minus-greaterthan) - [What Does “––>” Mean in Java?](https://www.baeldung.com/java-minus-minus-greaterthan)
- [All the Ways Java Uses the Colon Character](https://www.baeldung.com/java-colon) - [All the Ways Java Uses the Colon Character](https://www.baeldung.com/java-colon)
- [Convert Infix to Postfix Expressions in Java](https://www.baeldung.com/java-convert-infix-to-postfix-expressions)

View File

@ -6,3 +6,5 @@
- [URL Query Manipulation in Java](https://www.baeldung.com/java-url-query-manipulation) - [URL Query Manipulation in Java](https://www.baeldung.com/java-url-query-manipulation)
- [Understanding the java.net.SocketException Broken Pipe Error](https://www.baeldung.com/java-socketexception-broken-pipe-error) - [Understanding the java.net.SocketException Broken Pipe Error](https://www.baeldung.com/java-socketexception-broken-pipe-error)
- [Normalize a URL in Java](https://www.baeldung.com/java-url-normalization) - [Normalize a URL in Java](https://www.baeldung.com/java-url-normalization)
- [Translating Space Characters in URLEncoder](https://www.baeldung.com/java-urlencoder-translate-space-characters)
- [Creating a Custom URL Connection](https://www.baeldung.com/java-custom-url-connection)

View File

@ -31,11 +31,6 @@
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version> <version>${jackson.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.core.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId> <artifactId>spring-core</artifactId>

View File

@ -0,0 +1,38 @@
package com.baeldung.streams.range;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class StreamRangeUnitTest {
@Test
public void whenRangeStreamUsingLimitSkip_thenPrintsRange() {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> expectedRange = Arrays.asList(3, 4, 5, 6, 7);
List<Integer> range = numbers.stream()
.skip(2)
.limit(5)
.collect(Collectors.toList());
assertEquals(expectedRange, range);
}
@Test
public void whenRangeStreamUsingCollectingAndThen_thenPrintsRange() {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> expectedRange = Arrays.asList(3, 4, 5, 6, 7);
List<Integer> range = numbers.stream()
.filter(n -> n >= 3 && n <= 7)
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
assertEquals(expectedRange, range);
}
}

View File

@ -15,3 +15,4 @@
- [Simple Morse Code Translation in Java](https://www.baeldung.com/java-morse-code-english-translate) - [Simple Morse Code Translation in Java](https://www.baeldung.com/java-morse-code-english-translate)
- [How to Determine if a String Contains Invalid Encoded Characters](https://www.baeldung.com/java-check-string-contains-invalid-encoded-characters) - [How to Determine if a String Contains Invalid Encoded Characters](https://www.baeldung.com/java-check-string-contains-invalid-encoded-characters)
- [Regular Expression for Password Validation in Java](https://www.baeldung.com/java-regex-password-validation) - [Regular Expression for Password Validation in Java](https://www.baeldung.com/java-regex-password-validation)
- [Mask an Email Address and Phone Number in Java](https://www.baeldung.com/java-mask-email-address-phone-number)

View File

@ -1,2 +1,2 @@
### Relevant Articles: ### Relevant Articles:
- [Count Uppercase and Lowercase Letters in a String](https://www.baeldung.com/java-string-count-letters-uppercase-lowercase)

View File

@ -13,42 +13,6 @@
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
</parent> </parent>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${apache.commons.lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>${commons-text.version}</version>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>4.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>4.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
</dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
@ -65,8 +29,6 @@
<properties> <properties>
<maven.compiler.source>11</maven.compiler.source> <maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target> <maven.compiler.target>11</maven.compiler.target>
<apache.commons.lang3.version>3.13.0</apache.commons.lang3.version>
<commons-text.version>1.10.0</commons-text.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,40 @@
package com.baeldung.checkifstringisbased64;
import org.junit.jupiter.api.Test;
import java.util.Base64;
import java.util.regex.Pattern;
import static org.junit.jupiter.api.Assertions.*;
public class CheckIfStringIsBased64UnitTest {
@Test
public void givenBase64EncodedString_whenDecoding_thenNoException() {
try {
Base64.getDecoder().decode("SGVsbG8gd29ybGQ=");
assertTrue(true);
} catch (IllegalArgumentException e) {
fail("Unexpected exception: " + e.getMessage());
}
}
@Test
public void givenNonBase64String_whenDecoding_thenCatchException() {
try {
Base64.getDecoder().decode("Hello world!");
fail("Expected IllegalArgumentException was not thrown");
} catch (IllegalArgumentException e) {
assertTrue(true);
}
}
@Test
public void givenString_whenOperatingRegex_thenCheckIfItIsBase64Encoded() {
Pattern BASE64_PATTERN = Pattern.compile(
"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
);
assertTrue(BASE64_PATTERN.matcher("SGVsbG8gd29ybGQ=").matches());
}
}

View File

@ -0,0 +1,90 @@
package com.baeldung.countupperandlowercasechars;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class CountUpperAndLowercaseCharsUnitTest {
private static final String MY_STRING = "Hi, Welcome to Baeldung! Let's count letters!";
@Test
void whenUsingCountByCharacterRange_thenGetExpectedResult() {
LetterCount result = LetterCount.countByCharacterRange(MY_STRING);
assertEquals(4, result.getUppercaseCount());
assertEquals(31, result.getLowercaseCount());
}
@Test
void whenUsingCountByCharacterIsLowerOrUpperCase_thenGetExpectedResult() {
LetterCount result = LetterCount.countByCharacterIsUpperLower(MY_STRING);
assertEquals(4, result.getUppercaseCount());
assertEquals(31, result.getLowercaseCount());
}
@Test
void whenUsingCountByStreamApi_thenGetExpectedResult() {
LetterCount result = LetterCount.countByStreamAPI(MY_STRING);
assertEquals(4, result.getUppercaseCount());
assertEquals(31, result.getLowercaseCount());
}
@Test
void whenUsingIsUpperCaseAndIsLowerCase_thenUnicodeCharactersCanBeChecked() {
assertTrue(Character.isLowerCase('ä'));
assertTrue(Character.isUpperCase('Ä'));
}
}
class LetterCount {
private int uppercaseCount;
private int lowercaseCount;
private LetterCount(int uppercaseCount, int lowercaseCount) {
this.uppercaseCount = uppercaseCount;
this.lowercaseCount = lowercaseCount;
}
public static LetterCount countByCharacterRange(String input) {
int upperCount = 0;
int lowerCount = 0;
for (char c : input.toCharArray()) {
if (c >= 'A' && c <= 'Z') {
upperCount++;
}
if (c >= 'a' && c <= 'z') {
lowerCount++;
}
}
return new LetterCount(upperCount, lowerCount);
}
public static LetterCount countByCharacterIsUpperLower(String input) {
int upperCount = 0;
int lowerCount = 0;
for (char c : input.toCharArray()) {
if (Character.isUpperCase(c)) {
upperCount++;
}
if (Character.isLowerCase(c)) {
lowerCount++;
}
}
return new LetterCount(upperCount, lowerCount);
}
public static LetterCount countByStreamAPI(String input) {
return new LetterCount(
(int) input.chars().filter(Character::isUpperCase).count(),
(int) input.chars().filter(Character::isLowerCase).count()
);
}
public int getUppercaseCount() {
return uppercaseCount;
}
public int getLowercaseCount() {
return lowercaseCount;
}
}

View File

@ -0,0 +1,59 @@
package com.baeldung.findlargestnuminstring;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class FindLargestNumInStringUnitTest {
String inputString = "The numbers are 10, 20, and 5";
int expectedLargestNumber = 20;
@Test
public void givenInputString_whenUsingBasicApproach_thenFindingLargestNumber() {
String[] numbers = inputString.split("[^0-9]+");
int largestNumber = Integer.MIN_VALUE;
for (String number : numbers) {
if (!number.isEmpty()) {
int currentNumber = Integer.parseInt(number);
if (currentNumber > largestNumber) {
largestNumber = currentNumber;
}
}
}
assertEquals(expectedLargestNumber, largestNumber);
}
@Test
public void givenInputString_whenUsingRegularExpression_thenFindingLargestNumber() {
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(inputString);
int largestNumber = Integer.MIN_VALUE;
while (matcher.find()) {
int currentNumber = Integer.parseInt(matcher.group());
if (currentNumber > largestNumber) {
largestNumber = currentNumber;
}
}
assertEquals(expectedLargestNumber, largestNumber);
}
@Test
public void givenInputString_whenUsingStreamAndLambdaExpression_thenFindingLargestNumber() {
int largestNumber = Arrays.stream(inputString.split("[^0-9]+"))
.filter(s -> !s.isEmpty())
.mapToInt(Integer::parseInt)
.max()
.orElse(Integer.MIN_VALUE);
assertEquals(expectedLargestNumber, largestNumber);
}
}

View File

@ -18,18 +18,17 @@
<dependency> <dependency>
<groupId>com.fasterxml.jackson.jr</groupId> <groupId>com.fasterxml.jackson.jr</groupId>
<artifactId>jackson-jr-all</artifactId> <artifactId>jackson-jr-all</artifactId>
<version>2.15.2</version> <version>${jackson.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.jr</groupId> <groupId>com.fasterxml.jackson.jr</groupId>
<artifactId>jackson-jr-annotation-support</artifactId> <artifactId>jackson-jr-annotation-support</artifactId>
<version>2.15.2</version> <version>${jackson.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>RELEASE</version> <version>${lombok.version}</version>
<scope>compile</scope>
</dependency> </dependency>
</dependencies> </dependencies>
@ -44,4 +43,8 @@
</resources> </resources>
</build> </build>
<properties>
<jackson.version>2.16.0</jackson.version>
</properties>
</project> </project>

View File

@ -112,12 +112,6 @@
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>2.11.0</version> <version>2.11.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>javax.annotation</groupId> <groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId> <artifactId>javax.annotation-api</artifactId>

View File

@ -6,3 +6,4 @@ This module contains articles about JSON Conversions
- [Convert JSON Array to Java List](https://www.baeldung.com/java-convert-json-array-to-list) - [Convert JSON Array to Java List](https://www.baeldung.com/java-convert-json-array-to-list)
- [Reading JSON Documents as Maps and Comparing Them](https://www.baeldung.com/java-json-maps-comparison) - [Reading JSON Documents as Maps and Comparing Them](https://www.baeldung.com/java-json-maps-comparison)
- [Convert Byte Array to JSON and Vice Versa in Java](https://www.baeldung.com/java-json-byte-array-conversion) - [Convert Byte Array to JSON and Vice Versa in Java](https://www.baeldung.com/java-json-byte-array-conversion)
- [Preventing Gson from Expressing Integers as Floats](https://www.baeldung.com/java-gson-prevent-expressing-integers-as-floats)

View File

@ -1,22 +0,0 @@
package com.baeldung.preventexpressingintasfloat;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Hashtable;
public class Main {
public static String draft = "[{\"id\":4077395,\"field_id\":242566,\"body\":\"\"}, " +
"{\"id\":4077398,\"field_id\":242569,\"body\":[[273019,0],[273020,1],[273021,0]]}, " +
"{\"id\":4077399,\"field_id\":242570,\"body\":[[273022,0],[273023,1],[273024,0]]}]";
public static void main(String[] args) {
ArrayList<Hashtable<String, Object>> responses;
Type ResponseList = new TypeToken<ArrayList<Hashtable<String, Object>>>() {
}.getType();
responses = new Gson().fromJson(draft, ResponseList);
System.out.println(responses);
}
}

View File

@ -14,17 +14,24 @@ public class PreventExpressingIntAsFloatUnitTest {
public String jsonString = "[{\"id\":4077395,\"field_id\":242566,\"body\":\"\"}, " + public String jsonString = "[{\"id\":4077395,\"field_id\":242566,\"body\":\"\"}, " +
"{\"id\":4077398,\"field_id\":242569,\"body\":[[273019,0],[273020,1],[273021,0]]}, " + "{\"id\":4077398,\"field_id\":242569,\"body\":[[273019,0],[273020,1],[273021,0]]}, " +
"{\"id\":4077399,\"field_id\":242570,\"body\":[[273022,0],[273023,1],[273024,0]]}]"; "{\"id\":4077399,\"field_id\":242570,\"body\":[[273022,0],[273023,1],[273024,0]]}]";
public String expectedOutput = "[{body=, field_id=242566, id=4077395}, " + public String expectedOutput = "[{body=, field_id=242566, id=4077395}, " +
"{body=[[273019, 0], [273020, 1], [273021, 0]], field_id=242569, id=4077398}, " + "{body=[[273019, 0], [273020, 1], [273021, 0]], field_id=242569, id=4077398}, " +
"{body=[[273022, 0], [273023, 1], [273024, 0]], field_id=242570, id=4077399}]"; "{body=[[273022, 0], [273023, 1], [273024, 0]], field_id=242570, id=4077399}]";
public String defaultOutput = "[{body=, field_id=242566.0, id=4077395.0}, " +
"{body=[[273019.0, 0.0], [273020.0, 1.0], [273021.0, 0.0]], field_id=242569.0, id=4077398.0}, " +
"{body=[[273022.0, 0.0], [273023.0, 1.0], [273024.0, 0.0]], field_id=242570.0, id=4077399.0}]";
@Test @Test
public void givenJsonString_whenUsingsetObjectToNumberStrategyMethod_thenValidateOutput() { public void givenJsonString_whenUsingSetObjectToNumberStrategyMethod_thenValidateOutput() {
Gson gson = new GsonBuilder().setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE).create(); Gson defaultGson = new Gson();
ArrayList<Hashtable<String, Object>> responses = gson.fromJson(jsonString, new TypeToken<ArrayList<Hashtable<String, Object>>>() { ArrayList<Hashtable<String, Object>> defaultResponses = defaultGson.fromJson(jsonString, new TypeToken<ArrayList<Hashtable<String, Object>>>() {
}.getType()); }.getType());
assertEquals(expectedOutput, responses.toString()); Gson customGson = new GsonBuilder().setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE).create();
ArrayList<Hashtable<String, Object>> customResponses = customGson.fromJson(jsonString, new TypeToken<ArrayList<Hashtable<String, Object>>>() {
}.getType());
assertEquals(defaultOutput, defaultResponses.toString());
assertEquals(expectedOutput, customResponses.toString());
} }
} }

View File

@ -48,6 +48,7 @@
<dependency> <dependency>
<groupId>org.apache.activemq</groupId> <groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-server</artifactId> <artifactId>artemis-jms-server</artifactId>
<version>${activemq.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -65,4 +66,8 @@
</plugins> </plugins>
</build> </build>
<properties>
<activemq.version>2.32.0</activemq.version>
</properties>
</project> </project>

View File

@ -10,3 +10,4 @@ Since this is a module tied to an e-book, it should **not** be moved or used to
### Relevant Articles ### Relevant Articles
- [Apache Maven Tutorial](https://www.baeldung.com/maven) - [Apache Maven Tutorial](https://www.baeldung.com/maven)
- [Run Maven From Java Code](https://www.baeldung.com/java-maven-run-program)

View File

@ -88,7 +88,7 @@
<micrometer-registry-atlas.version>1.11.0</micrometer-registry-atlas.version> <micrometer-registry-atlas.version>1.11.0</micrometer-registry-atlas.version>
<spring-boot-starter-web.version>3.1.0</spring-boot-starter-web.version> <spring-boot-starter-web.version>3.1.0</spring-boot-starter-web.version>
<metrics-aspectj-deps.version>1.2.0</metrics-aspectj-deps.version> <metrics-aspectj-deps.version>1.2.0</metrics-aspectj-deps.version>
<spectator-api.version>1.5.4</spectator-api.version> <spectator-api.version>1.7.7</spectator-api.version>
</properties> </properties>
</project> </project>

View File

@ -282,7 +282,7 @@ public class MicrometerAtlasManualTest {
Map<Double, Double> expectedMicrometer = new TreeMap<>(); Map<Double, Double> expectedMicrometer = new TreeMap<>();
expectedMicrometer.put(2.5E7,1D); expectedMicrometer.put(2.5E7,1D);
expectedMicrometer.put(3.0E8,1D); expectedMicrometer.put(3.0E8,1D);
expectedMicrometer.put(6.0E8,4D); expectedMicrometer.put(6.0E8,1D);
Map<Double, Double> actualMicrometer = new TreeMap<>(); Map<Double, Double> actualMicrometer = new TreeMap<>();
HistogramSnapshot snapshot = timer.takeSnapshot(); HistogramSnapshot snapshot = timer.takeSnapshot();

View File

@ -8,6 +8,7 @@ import com.netflix.servo.monitor.Monitors;
import com.netflix.servo.tag.BasicTag; import com.netflix.servo.tag.BasicTag;
import com.netflix.servo.tag.BasicTagList; import com.netflix.servo.tag.BasicTagList;
import com.netflix.servo.tag.TagList; import com.netflix.servo.tag.TagList;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.util.Iterator; import java.util.Iterator;
@ -24,6 +25,12 @@ import static org.junit.Assert.assertTrue;
public class MetricAnnotationManualTest extends MetricTestBase { public class MetricAnnotationManualTest extends MetricTestBase {
static {
System.setProperty(
"com.netflix.servo.DefaultMonitorRegistry.registryClass",
"com.netflix.servo.jmx.JmxMonitorRegistry");
}
@Monitor(name = "integerCounter", type = DataSourceType.COUNTER, description = "Total number of update operations.") @Monitor(name = "integerCounter", type = DataSourceType.COUNTER, description = "Total number of update operations.")
private final AtomicInteger updateCount = new AtomicInteger(0); private final AtomicInteger updateCount = new AtomicInteger(0);

View File

@ -24,6 +24,12 @@ import static org.junit.Assert.assertThat;
public class MetricObserverManualTest extends MetricTestBase { public class MetricObserverManualTest extends MetricTestBase {
static {
System.setProperty(
"com.netflix.servo.DefaultMonitorRegistry.registryClass",
"com.netflix.servo.jmx.JmxMonitorRegistry");
}
@Test @Test
public void givenMetrics_whenRegister_thenMonitored() throws InterruptedException { public void givenMetrics_whenRegister_thenMonitored() throws InterruptedException {
Gauge<Double> gauge = new BasicGauge<>(MonitorConfig Gauge<Double> gauge = new BasicGauge<>(MonitorConfig

View File

@ -229,8 +229,8 @@
<maven-jar-plugin.version>3.3.0</maven-jar-plugin.version> <maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
<maven-resources-plugin.version>3.3.0</maven-resources-plugin.version> <maven-resources-plugin.version>3.3.0</maven-resources-plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version> <maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<spring-boot.version>3.1.5</spring-boot.version> <spring-boot.version>3.2.2</spring-boot.version>
<junit-jupiter.version>5.8.2</junit-jupiter.version> <junit-jupiter.version>5.10.2</junit-jupiter.version>
<native-build-tools-plugin.version>0.9.17</native-build-tools-plugin.version> <native-build-tools-plugin.version>0.9.17</native-build-tools-plugin.version>
<logback.version>1.4.4</logback.version> <logback.version>1.4.4</logback.version>
<slf4j.version>2.0.3</slf4j.version> <slf4j.version>2.0.3</slf4j.version>

View File

@ -1,2 +1,3 @@
## Relevant Articles ## Relevant Articles
- [Convert ResultSet Into Map](https://www.baeldung.com/java-resultset-map) - [Convert ResultSet Into Map](https://www.baeldung.com/java-resultset-map)
- [Pagination With JDBC](https://www.baeldung.com/java-jdbc-pagination)

View File

@ -12,3 +12,4 @@ This module contains articles about Annotations used in Hibernate.
- [@Immutable in Hibernate](https://www.baeldung.com/hibernate-immutable) - [@Immutable in Hibernate](https://www.baeldung.com/hibernate-immutable)
- [Hibernate @CreationTimestamp and @UpdateTimestamp](https://www.baeldung.com/hibernate-creationtimestamp-updatetimestamp) - [Hibernate @CreationTimestamp and @UpdateTimestamp](https://www.baeldung.com/hibernate-creationtimestamp-updatetimestamp)
- [Difference Between @JoinColumn and @PrimaryKeyJoinColumn in JPA](https://www.baeldung.com/java-jpa-join-vs-primarykeyjoin) - [Difference Between @JoinColumn and @PrimaryKeyJoinColumn in JPA](https://www.baeldung.com/java-jpa-join-vs-primarykeyjoin)
- [A Guide to the @SoftDelete Annotation in Hibernate](https://www.baeldung.com/java-hibernate-softdelete-annotation)

View File

@ -34,7 +34,7 @@ public class CodeGenerationIntegrationTest {
Connection conn = DriverManager.getConnection("jdbc:h2:mem:tes;INIT=CREATE SCHEMA IF NOT EXISTS \"public\""); Connection conn = DriverManager.getConnection("jdbc:h2:mem:tes;INIT=CREATE SCHEMA IF NOT EXISTS \"public\"");
context = DSL.using(conn, SQLDialect.H2); context = DSL.using(conn, SQLDialect.H2);
context.createTable(Author.AUTHOR) context.createTableIfNotExists(Author.AUTHOR)
.columns( .columns(
Author.AUTHOR.ID, Author.AUTHOR.ID,
Author.AUTHOR.FIRST_NAME, Author.AUTHOR.FIRST_NAME,
@ -42,7 +42,7 @@ public class CodeGenerationIntegrationTest {
Author.AUTHOR.AGE Author.AUTHOR.AGE
) )
.execute(); .execute();
context.createTable(Article.ARTICLE) context.createTableIfNotExists(Article.ARTICLE)
.columns( .columns(
Article.ARTICLE.ID, Article.ARTICLE.ID,
Article.ARTICLE.TITLE, Article.ARTICLE.TITLE,

View File

@ -37,7 +37,7 @@ public class CrudIntegrationTest {
Connection conn = DriverManager.getConnection("jdbc:h2:mem:tes;INIT=CREATE SCHEMA IF NOT EXISTS \"public\""); Connection conn = DriverManager.getConnection("jdbc:h2:mem:tes;INIT=CREATE SCHEMA IF NOT EXISTS \"public\"");
context = DSL.using(conn, SQLDialect.H2); context = DSL.using(conn, SQLDialect.H2);
context.createTable(Author.AUTHOR) context.createTableIfNotExists(Author.AUTHOR)
.columns( .columns(
Author.AUTHOR.ID, Author.AUTHOR.ID,
Author.AUTHOR.FIRST_NAME, Author.AUTHOR.FIRST_NAME,
@ -45,7 +45,7 @@ public class CrudIntegrationTest {
Author.AUTHOR.AGE Author.AUTHOR.AGE
) )
.execute(); .execute();
context.createTable(Article.ARTICLE) context.createTableIfNotExists(Article.ARTICLE)
.columns( .columns(
Article.ARTICLE.ID, Article.ARTICLE.ID,
Article.ARTICLE.TITLE, Article.ARTICLE.TITLE,

View File

@ -0,0 +1,69 @@
package com.baeldung.findby;
import jakarta.persistence.*;
import java.sql.Timestamp;
@Entity
@Table(name = "ACCOUNTS")
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "accounts_seq")
@SequenceGenerator(name = "accounts_seq", sequenceName = "accounts_seq", allocationSize = 1)
@Column(name = "user_id")
private int userId;
private String username;
private String password;
private String email;
private Timestamp createdOn;
private Timestamp lastLogin;
@OneToOne
@JoinColumn(name = "permissions_id")
private Permission permission;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setEmail(String email) {
this.email = email;
}
public Timestamp getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Timestamp createdOn) {
this.createdOn = createdOn;
}
public void setLastLogin(Timestamp lastLogin) {
this.lastLogin = lastLogin;
}
public Permission getPermission() {
return permission;
}
public void setPermission(Permission permission) {
this.permission = permission;
}
public String getEmail() {
return email;
}
@Override
public String toString() {
return "Account{" + "userId=" + userId + ", username='" + username + '\'' + ", password='" + password + '\'' + ", email='" + email + '\'' + ", createdOn=" + createdOn + ", lastLogin=" + lastLogin + ", permission=" + permission + '}';
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.findby;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AccountApplication {
public static void main(String[] args) {
SpringApplication.run(AccountApplication.class, args);
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.findby;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface AccountRepository extends JpaRepository<Account, Integer> {
Account findByEmail(String email);
Account findByUsernameAndEmail(String username, String email);
Account findByUsernameOrEmail(String username, String email);
List<Account> findByUsernameInOrEmailIn(List<String> usernames, List<String> emails);
}

View File

@ -0,0 +1,24 @@
package com.baeldung.findby;
import jakarta.persistence.*;
@Entity
@Table(name = "PERMISSIONS")
public class Permission {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "permissions_id_sq")
@SequenceGenerator(name = "permissions_id_sq", sequenceName = "permissions_id_sq", allocationSize = 1)
private int id;
private String type;
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return "Permission{" + "id=" + id + ", type='" + type + '\'' + '}';
}
}

View File

@ -0,0 +1,9 @@
package com.baeldung.findby;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface PermissionRepository extends JpaRepository<Permission, Integer> {
Permission findByType(String type);
}

View File

@ -0,0 +1,105 @@
package com.baeldung.boot.findby;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.baeldung.findby.Account;
import com.baeldung.findby.AccountApplication;
import com.baeldung.findby.AccountRepository;
import com.baeldung.findby.Permission;
import com.baeldung.findby.PermissionRepository;
@SpringBootTest(classes = AccountApplication.class)
public class AccountRepositoryUnitTest {
@Autowired
private AccountRepository accountRepository;
@Autowired
private PermissionRepository permissionRepository;
@BeforeEach
void setup() {
saveAccount();
}
@AfterEach
void tearDown() {
accountRepository.deleteAll();
permissionRepository.deleteAll();
}
@Test
void givenAccountInDb_whenPerformFindByEmail_thenReturnsAccount() {
String email = "test@test.com";
Account account = accountRepository.findByEmail(email);
assertThat(account.getEmail()).isEqualTo(email);
}
@Test
void givenAccountInDb_whenPerformFindByUsernameAndEmail_thenReturnsAccount() {
String email = "test@test.com";
String username = "user_admin";
Account account = accountRepository.findByUsernameAndEmail(username, email);
assertThat(account.getUsername()).isEqualTo(username);
assertThat(account.getEmail()).isEqualTo(email);
}
@Test
void givenAccountInDb_whenPerformFindByUsernameOrEmail_thenReturnsAccount() {
String email = "test@test.com";
String username = "user_editor";
Account account = accountRepository.findByUsernameOrEmail(username, email);
assertThat(account.getUsername()).isNotEqualTo(username);
assertThat(account.getEmail()).isEqualTo(email);
}
@Test
void givenAccountInDb_whenPerformFindByUsernameInOrEmailIn_thenReturnsAccounts() {
List<String> emails = Arrays.asList("test@test.com", "abc@abc.com", "pqr@pqr.com");
List<String> usernames = Arrays.asList("user_editor", "user_admin");
List<Account> byUsernameInOrEmailIn = accountRepository.findByUsernameInOrEmailIn(usernames, emails);
assertThat(byUsernameInOrEmailIn.size()).isEqualTo(1);
assertThat(byUsernameInOrEmailIn.get(0)
.getEmail()).isEqualTo("test@test.com");
}
private Permission getPermissions() {
Permission editor = new Permission();
editor.setType("editor");
permissionRepository.save(editor);
return editor;
}
private void saveAccount() {
List<List<String>> sampleRecords = Arrays.asList(
Arrays.asList("test@test.com", "user_admin"),
Arrays.asList("test1@test.com", "user_admin_1"),
Arrays.asList("test2@test.com", "user_admin_2")
);
sampleRecords.forEach(sampleRecord -> {
Account account = new Account();
account.setEmail(sampleRecord.get(0));
account.setUsername(sampleRecord.get(1));
account.setPermission(getPermissions());
account.setPassword(UUID.randomUUID()
.toString());
account.setCreatedOn(Timestamp.from(Instant.now()));
account.setLastLogin(Timestamp.from(Instant.now()));
accountRepository.save(account);
System.out.println(account.toString());
});
}
}

View File

@ -2,3 +2,4 @@
- [Scroll API in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-scroll-api) - [Scroll API in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-scroll-api)
- [List vs. Set in @OneToMany JPA](https://www.baeldung.com/spring-jpa-onetomany-list-vs-set) - [List vs. Set in @OneToMany JPA](https://www.baeldung.com/spring-jpa-onetomany-list-vs-set)
- [N+1 Problem in Hibernate and Spring Data JPA](https://www.baeldung.com/spring-hibernate-n1-problem) - [N+1 Problem in Hibernate and Spring Data JPA](https://www.baeldung.com/spring-hibernate-n1-problem)
- [Get All Results at Once in a Spring Boot Paged Query Method](https://www.baeldung.com/spring-boot-paged-query-all-results)

View File

@ -194,6 +194,7 @@
<lifecycle-mapping.version>1.0.0</lifecycle-mapping.version> <lifecycle-mapping.version>1.0.0</lifecycle-mapping.version>
<sql-maven-plugin.version>1.5</sql-maven-plugin.version> <sql-maven-plugin.version>1.5</sql-maven-plugin.version>
<properties-maven-plugin.version>1.0.0</properties-maven-plugin.version> <properties-maven-plugin.version>1.0.0</properties-maven-plugin.version>
<spring-boot.version>3.1.5</spring-boot.version>
</properties> </properties>
</project> </project>

View File

@ -84,6 +84,7 @@
<mybatis.version>3.5.2</mybatis.version> <mybatis.version>3.5.2</mybatis.version>
<mybatis-spring-boot-starter.version>3.0.3</mybatis-spring-boot-starter.version> <mybatis-spring-boot-starter.version>3.0.3</mybatis-spring-boot-starter.version>
<spring-boot.repackage.skip>true</spring-boot.repackage.skip> <spring-boot.repackage.skip>true</spring-boot.repackage.skip>
<spring-boot.version>3.1.5</spring-boot.version>
</properties> </properties>
</project> </project>

34
pom.xml
View File

@ -328,12 +328,6 @@
</build> </build>
<modules> <modules>
<module>parent-boot-1</module>
<module>parent-boot-2</module>
<module>parent-spring-4</module>
<module>parent-spring-5</module>
<module>parent-spring-6</module>
<!-- <module>clojure-modules</module> --> <!-- Not a maven project --> <!-- <module>clojure-modules</module> --> <!-- Not a maven project -->
<module>core-java-modules/core-java-8</module> <module>core-java-modules/core-java-8</module>
@ -404,12 +398,6 @@
</build> </build>
<modules> <modules>
<module>parent-boot-1</module>
<module>parent-boot-2</module>
<module>parent-spring-4</module>
<module>parent-spring-5</module>
<module>parent-spring-6</module>
<module>spring-4</module> <module>spring-4</module>
<module>spring-6</module> <module>spring-6</module>
@ -460,12 +448,6 @@
</build> </build>
<modules> <modules>
<module>parent-boot-1</module>
<module>parent-boot-2</module>
<module>parent-spring-4</module>
<module>parent-spring-5</module>
<module>parent-spring-6</module>
<module>apache-spark</module> <module>apache-spark</module>
<module>jhipster-modules</module> <module>jhipster-modules</module>
<module>web-modules/restx</module> <module>web-modules/restx</module>
@ -498,12 +480,6 @@
</build> </build>
<modules> <modules>
<module>parent-boot-1</module>
<module>parent-boot-2</module>
<module>parent-spring-4</module>
<module>parent-spring-5</module>
<module>parent-spring-6</module>
<!-- <module>clojure-modules</module> --> <!-- Not a maven project --> <!-- <module>clojure-modules</module> --> <!-- Not a maven project -->
<module>core-java-modules/core-java-8</module> <module>core-java-modules/core-java-8</module>
@ -683,6 +659,11 @@
</build> </build>
<modules> <modules>
<module>parent-boot-1</module>
<module>parent-boot-2</module>
<module>parent-spring-4</module>
<module>parent-spring-5</module>
<module>parent-spring-6</module>
<module>akka-modules</module> <module>akka-modules</module>
<module>algorithms-modules</module> <module>algorithms-modules</module>
<module>apache-cxf-modules</module> <module>apache-cxf-modules</module>
@ -924,6 +905,11 @@
</build> </build>
<modules> <modules>
<module>parent-boot-1</module>
<module>parent-boot-2</module>
<module>parent-spring-4</module>
<module>parent-spring-5</module>
<module>parent-spring-6</module>
<module>akka-modules</module> <module>akka-modules</module>
<module>algorithms-modules</module> <module>algorithms-modules</module>
<module>apache-cxf-modules</module> <module>apache-cxf-modules</module>

View File

@ -0,0 +1,2 @@
### Relevant Articles
- [Quarkus and Virtual Threads](https://www.baeldung.com/java-quarkus-virtual-threads)

View File

@ -8,4 +8,5 @@ This module contains articles about Spring aspect oriented programming (AOP)
- [When Does Java Throw UndeclaredThrowableException?](https://www.baeldung.com/java-undeclaredthrowableexception) - [When Does Java Throw UndeclaredThrowableException?](https://www.baeldung.com/java-undeclaredthrowableexception)
- [Get Advised Method Info in Spring AOP](https://www.baeldung.com/spring-aop-get-advised-method-info) - [Get Advised Method Info in Spring AOP](https://www.baeldung.com/spring-aop-get-advised-method-info)
- [Invoke Spring @Cacheable from Another Method of Same Bean](https://www.baeldung.com/spring-invoke-cacheable-other-method-same-bean) - [Invoke Spring @Cacheable from Another Method of Same Bean](https://www.baeldung.com/spring-invoke-cacheable-other-method-same-bean)
- [Logging With AOP in Spring](https://www.baeldung.com/spring-aspect-oriented-programming-logging)
- More articles: [[<-- prev]](/spring-aop) - More articles: [[<-- prev]](/spring-aop)

View File

@ -0,0 +1,11 @@
package com.baeldung.logging;
import org.springframework.stereotype.Service;
@Service
public class GreetingService {
public String greet(String name) {
return String.format("Hello %s", name);
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.logging;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class GreetingServiceWithoutAOP {
private static final Logger logger = LoggerFactory.getLogger(GreetingServiceWithoutAOP.class);
public String greet(String name) {
logger.info(">> greet() - {}", name);
String result = String.format("Hello %s", name);
logger.info("<< greet() - {}", result);
return result;
}
}

View File

@ -0,0 +1,55 @@
package com.baeldung.logging;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Aspect
@Component
public class LoggingAspect {
private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);
@Pointcut("execution(public * com.baeldung.logging.*.*(..))")
private void publicMethodsFromLoggingPackage() {
}
@Before(value = "publicMethodsFromLoggingPackage()")
public void logBefore(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
String methodName = joinPoint.getSignature().getName();
logger.info(">> {}() - {}", methodName, Arrays.toString(args));
}
@AfterReturning(value = "publicMethodsFromLoggingPackage()", returning = "result")
public void logAfter(JoinPoint joinPoint, Object result) {
String methodName = joinPoint.getSignature().getName();
logger.info("<< {}() - {}", methodName, result);
}
@AfterThrowing(pointcut = "publicMethodsFromLoggingPackage()", throwing = "exception")
public void logException(JoinPoint joinPoint, Throwable exception) {
String methodName = joinPoint.getSignature().getName();
logger.error("<< {}() - {}", methodName, exception.getMessage());
}
@Around(value = "publicMethodsFromLoggingPackage()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
String methodName = joinPoint.getSignature().getName();
logger.info(">> {}() - {}", methodName, Arrays.toString(args));
Object result = joinPoint.proceed();
logger.info("<< {}() - {}", methodName, result);
return result;
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.logging;
import com.baeldung.Application;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@SpringBootTest(classes = Application.class)
class GreetingServiceUnitTest {
@Autowired
private GreetingService greetingService;
@Test
void givenName_whenGreet_thenReturnCorrectResult() {
String result = greetingService.greet("Baeldung");
assertNotNull(result);
assertEquals("Hello Baeldung", result);
}
}

View File

@ -147,6 +147,7 @@
<resource.delimiter>@</resource.delimiter> <resource.delimiter>@</resource.delimiter>
<!-- <start-class>com.baeldung.buildproperties.Application</start-class> --> <!-- <start-class>com.baeldung.buildproperties.Application</start-class> -->
<start-class>com.baeldung.yaml.MyApplication</start-class> <start-class>com.baeldung.yaml.MyApplication</start-class>
<spring-boot.version>3.1.5</spring-boot.version>
</properties> </properties>
</project> </project>

View File

@ -53,6 +53,7 @@
<properties> <properties>
<apache.client5.version>5.0.3</apache.client5.version> <apache.client5.version>5.0.3</apache.client5.version>
<spring-boot.version>3.1.5</spring-boot.version>
</properties> </properties>
</project> </project>

View File

@ -10,9 +10,10 @@
<description>Spring Cloud Eureka Server and Sample Clients</description> <description>Spring Cloud Eureka Server and Sample Clients</description>
<parent> <parent>
<groupId>com.baeldung.spring.cloud</groupId> <groupId>com.baeldung</groupId>
<artifactId>spring-cloud-modules</artifactId> <artifactId>parent-boot-3</artifactId>
<version>1.0.0-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-3</relativePath>
</parent> </parent>
<modules> <modules>
@ -23,6 +24,10 @@
<module>spring-cloud-eureka-server</module> <module>spring-cloud-eureka-server</module>
</modules> </modules>
<properties>
<spring-cloud-dependencies.version>2023.0.0</spring-cloud-dependencies.version>
</properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@ -65,6 +65,7 @@
<properties> <properties>
<jinq.version>2.0.1</jinq.version> <jinq.version>2.0.1</jinq.version>
<hibernate-core.version>6.4.2.Final</hibernate-core.version> <hibernate-core.version>6.4.2.Final</hibernate-core.version>
<spring-boot.version>3.1.5</spring-boot.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,56 @@
package com.baeldung.spring.kafka.kafkaexception;
import java.lang.management.ManagementFactory;
import java.util.Properties;
import java.util.UUID;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.common.serialization.StringSerializer;
public class HandleInstanceAlreadyExistsException {
public static void generateUniqueClientIDUsingUUIDRandom() {
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", StringSerializer.class);
props.put("value.serializer", StringSerializer.class);
String clientId = "my-producer-" + UUID.randomUUID();
props.setProperty("client.id", clientId);
KafkaProducer<String, String> producer1 = new KafkaProducer<>(props);
clientId = "my-producer-" + UUID.randomUUID();
props.setProperty("client.id", clientId);
KafkaProducer<String, String> producer2 = new KafkaProducer<>(props);
}
public static void closeProducerProperlyBeforeReinstantiate() {
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("client.id", "my-producer");
props.put("key.serializer", StringSerializer.class);
props.put("value.serializer", StringSerializer.class);
KafkaProducer<String, String> producer1 = new KafkaProducer<>(props);
producer1.close();
producer1 = new KafkaProducer<>(props);
}
public static void useUniqueObjectName() throws Exception {
MBeanServer mBeanServer1 = ManagementFactory.getPlatformMBeanServer();
MBeanServer mBeanServer2 = ManagementFactory.getPlatformMBeanServer();
ObjectName objectName1 = new ObjectName("kafka.server:type=KafkaMetrics,id=metric1");
ObjectName objectName2 = new ObjectName("kafka.server:type=KafkaMetrics,id=metric2");
MyMBean mBean1 = new MyMBean();
mBeanServer1.registerMBean(mBean1, objectName1);
MyMBean mBean2 = new MyMBean();
mBeanServer2.registerMBean(mBean2, objectName2);
}
}

View File

@ -0,0 +1,12 @@
package com.baeldung.spring.kafka.kafkaexception;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class KafkaAppMain {
public static void main(String[] args) {
SpringApplication.run(KafkaAppMain.class, args);
}
}

View File

@ -0,0 +1,123 @@
package com.baeldung.spring.kafka.kafkaexception;
import java.lang.management.ManagementFactory;
import java.util.Properties;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.stereotype.Service;
@Service
public class SimulateInstanceAlreadyExistsException {
public static void jmxRegistrationConflicts() throws Exception {
// Create two instances of MBeanServer
MBeanServer mBeanServer1 = ManagementFactory.getPlatformMBeanServer();
MBeanServer mBeanServer2 = ManagementFactory.getPlatformMBeanServer();
// Define the same ObjectName for both MBeans
ObjectName objectName = new ObjectName("kafka.server:type=KafkaMetrics");
// Create and register the first MBean
MyMBean mBean1 = new MyMBean();
mBeanServer1.registerMBean(mBean1, objectName);
// Attempt to register the second MBean with the same ObjectName
MyMBean mBean2 = new MyMBean();
mBeanServer2.registerMBean(mBean2, objectName);
}
public static void duplicateConsumerClientID() {
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("client.id", "my-consumer");
props.put("group.id", "test-group");
props.put("key.deserializer", StringDeserializer.class);
props.put("value.deserializer", StringDeserializer.class);
// Simulating concurrent client creation by multiple threads
for (int i = 0; i < 3; i++) {
new Thread(() -> {
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
}).start();
}
}
public void duplicateProducerClientID() throws Exception {
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("client.id", "my-producer");
props.put("key.serializer", StringSerializer.class);
props.put("value.serializer", StringSerializer.class);
KafkaProducer<String, String> producer1 = new KafkaProducer<>(props);
// Attempting to create another producer using same client.id
KafkaProducer<String, String> producer2 = new KafkaProducer<>(props);
}
public static void unclosedProducerAndReinitialize() {
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("client.id", "my-producer");
props.put("key.serializer", StringSerializer.class);
props.put("value.serializer", StringSerializer.class);
KafkaProducer<String, String> producer1 = new KafkaProducer<>(props);
// Attempting to reinitialize without proper close
producer1 = new KafkaProducer<>(props);
}
}
class MyMBean implements DynamicMBean {
@Override
public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {
return null;
}
@Override
public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
}
@Override
public AttributeList getAttributes(String[] attributes) {
return null;
}
@Override
public AttributeList setAttributes(AttributeList attributes) {
return null;
}
@Override
public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException {
return null;
}
@Override
public MBeanInfo getMBeanInfo() {
MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[0];
MBeanConstructorInfo[] constructors = new MBeanConstructorInfo[0];
MBeanOperationInfo[] operations = new MBeanOperationInfo[0];
MBeanNotificationInfo[] notifications = new MBeanNotificationInfo[0];
return new MBeanInfo(MyMBean.class.getName(), "My MBean", attributes, constructors, operations, notifications);
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.spring.kafka.viewheaders;
import java.util.Map;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.KafkaHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;
@Service
public class KafkaMessageConsumer {
@KafkaListener(topics = { "my-topic" }, groupId = "my-consumer-group")
public void listen(@Payload String message, @Headers Map<String, Object> headers) {
System.out.println("Received message: " + message);
System.out.println("Headers:");
headers.forEach((key, value) -> System.out.println(key + ": " + value));
String topicName = (String) headers.get(KafkaHeaders.TOPIC);
System.out.println("Topic: " + topicName);
int partitionID = (int) headers.get(KafkaHeaders.RECEIVED_PARTITION_ID);
System.out.println("Partition ID: " + partitionID);
}
@KafkaListener(topics = { "my-topic" }, groupId = "my-consumer-group")
public void listen(@Payload String message, @Header(KafkaHeaders.RECEIVED_TOPIC) String topicName,
@Header(KafkaHeaders.RECEIVED_PARTITION_ID) int partition) {
System.out.println("Topic: " + topicName);
System.out.println("Partition ID: " + partition);
}
}

View File

@ -0,0 +1,63 @@
package com.baeldung.spring.kafka.viewheaders;
import java.util.HashMap;
import java.util.Map;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
@SpringBootApplication
public class Main {
@Autowired
static KafkaMessageConsumer kafkaMessageConsumer;
@Bean
public KafkaTemplate<String, String> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
@Bean
public ProducerFactory<String, String> producerFactory() {
Map<String, Object> configProps = new HashMap<>();
configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
return new DefaultKafkaProducerFactory<>(configProps);
}
@Bean
public KafkaConsumer<String, String> kafkaConsumer() {
Map<String, Object> configProps = new HashMap<>();
configProps.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
configProps.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
configProps.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
configProps.put(ConsumerConfig.GROUP_ID_CONFIG, "my-consumer-group");
return new KafkaConsumer<>(configProps);
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Main.class, args);
// Get the KafkaTemplate bean from the application context
KafkaTemplate<String, String> kafkaTemplate = context.getBean(KafkaTemplate.class);
// Send a message to the "my-topic" Kafka topic
String message = "Hello Baeldung!";
kafkaTemplate.send("my-topic", message);
// Close the application context
context.close();
}
}

View File

@ -116,7 +116,7 @@ public class KafkaConsumerConfig {
public ConcurrentKafkaListenerContainerFactory<String, Object> multiTypeKafkaListenerContainerFactory() { public ConcurrentKafkaListenerContainerFactory<String, Object> multiTypeKafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, Object> factory = new ConcurrentKafkaListenerContainerFactory<>(); ConcurrentKafkaListenerContainerFactory<String, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(multiTypeConsumerFactory()); factory.setConsumerFactory(multiTypeConsumerFactory());
factory.setMessageConverter(multiTypeConverter()); factory.setRecordMessageConverter(multiTypeConverter());
return factory; return factory;
} }

View File

@ -54,4 +54,8 @@
</plugins> </plugins>
</build> </build>
<properties>
<spring-boot.version>3.1.5</spring-boot.version>
</properties>
</project> </project>

View File

@ -10,7 +10,8 @@
<parent> <parent>
<groupId>com.baeldung</groupId> <groupId>com.baeldung</groupId>
<artifactId>spring-security-modules</artifactId> <artifactId>parent-boot-3</artifactId>
<relativePath>../../parent-boot-3</relativePath>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
</parent> </parent>

View File

@ -15,10 +15,6 @@
</parent> </parent>
<dependencies> <dependencies>
<!--<dependency> -->
<!--<groupId>org.springframework.boot</groupId> -->
<!--<artifactId>spring-boot-starter-actuator</artifactId> -->
<!--</dependency> -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId> <artifactId>spring-boot-starter-security</artifactId>

View File

@ -7,6 +7,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@ -27,18 +28,13 @@ public class BasicAuthConfiguration {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf() http.csrf(AbstractHttpConfigurer::disable)
.disable()
.cors(withDefaults()) .cors(withDefaults())
.authorizeRequests() .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry
.antMatchers(HttpMethod.OPTIONS, "/**") .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.permitAll() .requestMatchers("/login").permitAll()
.antMatchers("/login") .anyRequest().authenticated())
.permitAll() .httpBasic(withDefaults());
.anyRequest()
.authenticated()
.and()
.httpBasic();
return http.build(); return http.build();
} }
} }

View File

@ -3,7 +3,7 @@ package com.baeldung.springbootsecurityrest.controller;
import java.security.Principal; import java.security.Principal;
import java.util.Base64; import java.util.Base64;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;

View File

@ -29,17 +29,23 @@
<groupId>org.openapitools</groupId> <groupId>org.openapitools</groupId>
<artifactId>openapi-generator</artifactId> <artifactId>openapi-generator</artifactId>
<version>${openapi-generator.version}</version> <version>${openapi-generator.version}</version>
</dependency> <exclusions>
<dependency> <exclusion>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>org.slf4j</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>slf4j-simple</artifactId>
<version>${jackson-databind.version}</version> </exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springdoc</groupId> <groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId> <artifactId>springdoc-openapi-ui</artifactId>
<version>${springdoc.version}</version> <version>${springdoc.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>${jackson-databind-nullable.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -85,9 +91,9 @@
<springfox-version>3.0.0</springfox-version> <springfox-version>3.0.0</springfox-version>
<log4j2.version>2.17.1</log4j2.version> <log4j2.version>2.17.1</log4j2.version>
<springdoc.version>1.7.0</springdoc.version> <springdoc.version>1.7.0</springdoc.version>
<openapi-generator.version>3.3.4</openapi-generator.version> <openapi-generator.version>7.2.0</openapi-generator.version>
<jackson-databind.version>2.16.0</jackson-databind.version> <openapi-generator-maven-plugin.version>7.2.0</openapi-generator-maven-plugin.version>
<openapi-generator-maven-plugin.version>5.1.0</openapi-generator-maven-plugin.version> <jackson-databind-nullable.version>0.2.6</jackson-databind-nullable.version>
</properties> </properties>
</project> </project>

View File

@ -1,14 +1,29 @@
/** /**
* NOTE: This class is auto generated by OpenAPI Generator (https://com.baeldung.openapi-generator.tech) ({{{generatorVersion}}}). * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://com.baeldung.openapi-generator.tech * https://openapi-generator.tech
* Do not edit the class manually. * Do not edit the class manually.
*/ */
package {{package}}; package {{package}};
{{#imports}}import {{import}}; {{#imports}}import {{import}};
{{/imports}} {{/imports}}
import io.swagger.annotations.*;
import com.baeldung.openapi.petstore.validation.Capitalized; import com.baeldung.openapi.petstore.validation.Capitalized;
{{#swagger2AnnotationLibrary}}
import io.swagger.v3.oas.annotations.ExternalDocumentation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
{{/swagger2AnnotationLibrary}}
{{#swagger1AnnotationLibrary}}
import io.swagger.annotations.*;
{{/swagger1AnnotationLibrary}}
{{#jdk8-no-delegate}} {{#jdk8-no-delegate}}
{{#virtualService}} {{#virtualService}}
import io.virtualan.annotation.ApiVirtual; import io.virtualan.annotation.ApiVirtual;
@ -17,13 +32,23 @@ import io.virtualan.annotation.VirtualService;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
{{/jdk8-no-delegate}} {{/jdk8-no-delegate}}
{{^useResponseEntity}}
import org.springframework.http.HttpStatus;
{{/useResponseEntity}}
{{#useResponseEntity}}
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
{{/useResponseEntity}}
{{#useBeanValidation}} {{#useBeanValidation}}
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
{{/useBeanValidation}} {{/useBeanValidation}}
{{#vendorExtensions.x-spring-paginated}} {{#useSpringController}}
import org.springframework.data.domain.Pageable; {{#useResponseEntity}}
{{/vendorExtensions.x-spring-paginated}} import org.springframework.stereotype.Controller;
{{/useResponseEntity}}
{{^useResponseEntity}}
import org.springframework.web.bind.annotation.RestController;
{{/useResponseEntity}}
{{/useSpringController}}
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
{{#jdk8-no-delegate}} {{#jdk8-no-delegate}}
{{^reactive}} {{^reactive}}
@ -39,8 +64,8 @@ import org.springframework.http.codec.multipart.Part;
{{/reactive}} {{/reactive}}
{{#useBeanValidation}} {{#useBeanValidation}}
import javax.validation.Valid; import {{javaxPackage}}.validation.Valid;
import javax.validation.constraints.*; import {{javaxPackage}}.validation.constraints.*;
{{/useBeanValidation}} {{/useBeanValidation}}
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -53,17 +78,37 @@ import java.util.Optional;
{{/useOptional}} {{/useOptional}}
{{/jdk8-no-delegate}} {{/jdk8-no-delegate}}
{{#async}} {{#async}}
import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}}; import java.util.concurrent.CompletableFuture;
{{/async}} {{/async}}
import {{javaxPackage}}.annotation.Generated;
{{>generatedAnnotation}} {{>generatedAnnotation}}
{{#useBeanValidation}} {{#useBeanValidation}}
@Validated @Validated
{{/useBeanValidation}} {{/useBeanValidation}}
@Api(value = "{{{baseName}}}", tags = "All") {{#useSpringController}}
{{#useResponseEntity}}
@Controller
{{/useResponseEntity}}
{{^useResponseEntity}}
@RestController
{{/useResponseEntity}}
{{/useSpringController}}
{{#swagger2AnnotationLibrary}}
@Tag(name = "{{{tagName}}}", description = {{#tagDescription}}"{{{.}}}"{{/tagDescription}}{{^tagDescription}}"the {{{tagName}}} API"{{/tagDescription}})
{{/swagger2AnnotationLibrary}}
{{#swagger1AnnotationLibrary}}
@Api(value = "{{{tagName}}}", description = {{#tagDescription}}"{{{.}}}"{{/tagDescription}}{{^tagDescription}}"the {{{tagName}}} API"{{/tagDescription}})
{{/swagger1AnnotationLibrary}}
{{#operations}} {{#operations}}
{{#virtualService}} {{#virtualService}}
@VirtualService @VirtualService
{{/virtualService}} {{/virtualService}}
{{#useRequestMappingOnInterface}}
{{=<% %>=}}
@RequestMapping("${openapi.<%title%>.base-path:<%>defaultBasePath%>}")
<%={{ }}=%>
{{/useRequestMappingOnInterface}}
public interface {{classname}} { public interface {{classname}} {
{{#jdk8-default-interface}} {{#jdk8-default-interface}}
{{^isDelegate}} {{^isDelegate}}
@ -102,45 +147,127 @@ public interface {{classname}} {
* @see <a href="{{url}}">{{summary}} Documentation</a> * @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}} {{/externalDocs}}
*/ */
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
{{#virtualService}} {{#virtualService}}
@ApiVirtual @ApiVirtual
{{/virtualService}} {{/virtualService}}
@ApiOperation(value = "{{{summary}}}", nickname = "{{{operationId}}}", notes = "{{{notes}}}"{{#returnBaseType}}, response = {{{returnBaseType}}}.class{{/returnBaseType}}{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}}{{#hasAuthMethods}}, authorizations = { {{#swagger2AnnotationLibrary}}
{{#authMethods}}{{#isOAuth}}@Authorization(value = "{{name}}", scopes = { @Operation(
{{#scopes}}@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}}, operationId = "{{{operationId}}}",
{{/-last}}{{/scopes}} }){{^-last}},{{/-last}}{{/isOAuth}} {{#summary}}
{{^isOAuth}}@Authorization(value = "{{name}}"){{^-last}},{{/-last}} summary = "{{{.}}}",
{{/isOAuth}}{{/authMethods}} }{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}",{{/vendorExtensions.x-tags}} }) {{/summary}}
@ApiResponses(value = { {{#responses}} {{#notes}}
@ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{baseType}}}.class{{/baseType}}{{#containerType}}, responseContainer = "{{{containerType}}}"{{/containerType}}){{^-last}},{{/-last}}{{/responses}} }) description = "{{{.}}}",
{{#implicitHeaders}} {{/notes}}
@ApiImplicitParams({ {{#isDeprecated}}
{{#headerParams}} deprecated = true,
{{>implicitHeader}} {{/isDeprecated}}
{{/headerParams}} {{#vendorExtensions.x-tags.size}}
tags = { {{#vendorExtensions.x-tags}}"{{tag}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-tags}} },
{{/vendorExtensions.x-tags.size}}
responses = {
{{#responses}}
@ApiResponse(responseCode = {{#isDefault}}"default"{{/isDefault}}{{^isDefault}}"{{{code}}}"{{/isDefault}}, description = "{{{message}}}"{{#baseType}}, content = {
{{#produces}}
@Content(mediaType = "{{{mediaType}}}", {{#isArray}}array = @ArraySchema({{/isArray}}schema = @Schema(implementation = {{{baseType}}}.class){{#isArray}}){{/isArray}}){{^-last}},{{/-last}}
{{/produces}}
}{{/baseType}}){{^-last}},{{/-last}}
{{/responses}}
}{{#hasAuthMethods}},
security = {
{{#authMethods}}
@SecurityRequirement(name = "{{name}}"{{#scopes.0}}, scopes={ {{#scopes}}"{{scope}}"{{^-last}}, {{/-last}}{{/scopes}} }{{/scopes.0}}){{^-last}},{{/-last}}
{{/authMethods}}
}{{/hasAuthMethods}}{{#externalDocs}},
externalDocs = @ExternalDocumentation(description = "{{externalDocs.description}}", url = "{{externalDocs.url}}"){{/externalDocs}}
)
{{/swagger2AnnotationLibrary}}
{{#swagger1AnnotationLibrary}}
@ApiOperation(
{{#vendorExtensions.x-tags.size}}
tags = { {{#vendorExtensions.x-tags}}"{{tag}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-tags}} },
{{/vendorExtensions.x-tags.size}}
value = "{{{summary}}}",
nickname = "{{{operationId}}}",
notes = "{{{notes}}}"{{#returnBaseType}},
response = {{{.}}}.class{{/returnBaseType}}{{#returnContainer}},
responseContainer = "{{{.}}}"{{/returnContainer}}{{#hasAuthMethods}},
authorizations = {
{{#authMethods}}
{{#scopes.0}}
@Authorization(value = "{{name}}", scopes = {
{{#scopes}}
@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}},{{/-last}}
{{/scopes}}
}){{^-last}},{{/-last}}
{{/scopes.0}}
{{^scopes.0}}
@Authorization(value = "{{name}}"){{^-last}},{{/-last}}
{{/scopes.0}}
{{/authMethods}} }{{/hasAuthMethods}}
)
@ApiResponses({
{{#responses}}
@ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{.}}}.class{{/baseType}}{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}){{^-last}},{{/-last}}
{{/responses}}
}) })
{{/implicitHeaders}} {{/swagger1AnnotationLibrary}}
{{#implicitHeadersParams.0}}
{{#swagger2AnnotationLibrary}}
@Parameters({
{{#implicitHeadersParams}}
{{>paramDoc}}{{^-last}},{{/-last}}
{{/implicitHeadersParams}}
})
{{/swagger2AnnotationLibrary}}
{{#swagger1AnnotationLibrary}}
@ApiImplicitParams({
{{#implicitHeadersParams}}
{{>implicitHeader}}{{^-last}},{{/-last}}
{{/implicitHeadersParams}}
})
{{/swagger1AnnotationLibrary}}
{{/implicitHeadersParams.0}}
@RequestMapping( @RequestMapping(
method = RequestMethod.{{httpMethod}}, method = RequestMethod.{{httpMethod}},
value = "{{{path}}}"{{#singleContentTypes}}{{#hasProduces}}, value = "{{{path}}}"{{#singleContentTypes}}{{#hasProduces}},
produces = "{{{vendorExtensions.x-accepts}}}"{{/hasProduces}}{{#hasConsumes}}, produces = "{{{vendorExtensions.x-accepts}}}"{{/hasProduces}}{{#hasConsumes}},
consumes = "{{{vendorExtensions.x-contentType}}}"{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}}, consumes = "{{{vendorExtensions.x-content-type}}}"{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}},
produces = { {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }{{/hasProduces}}{{#hasConsumes}}, produces = { {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }{{/hasProduces}}{{#hasConsumes}},
consumes = { {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }{{/hasConsumes}}{{/singleContentTypes}} consumes = { {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }{{/hasConsumes}}{{/singleContentTypes}}{{#hasVersionHeaders}},
headers = { {{#vendorExtensions.versionHeaderParamsList}}"{{baseName}}{{#defaultValue}}={{{.}}}{{/defaultValue}}"{{^-last}}, {{/-last}}{{/vendorExtensions.versionHeaderParamsList}} } {{/hasVersionHeaders}}{{#hasVersionQueryParams}},
params = { {{#vendorExtensions.versionQueryParamsList}}"{{baseName}}{{#defaultValue}}={{{.}}}{{/defaultValue}}"{{^-last}}, {{/-last}}{{/vendorExtensions.versionQueryParamsList}} } {{/hasVersionQueryParams}}
) )
{{#jdk8-default-interface}}default {{/jdk8-default-interface}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}}{{^-last}},{{/-last}}{{#-last}}{{#reactive}}, {{/reactive}}{{/-last}}{{/allParams}}{{#reactive}}final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{^jdk8-default-interface}};{{/jdk8-default-interface}}{{#jdk8-default-interface}}{{#unhandledException}} throws Exception{{/unhandledException}} { {{^useResponseEntity}}
@ResponseStatus({{#springHttpStatus}}{{#responses.0}}{{{code}}}{{/responses.0}}{{/springHttpStatus}})
{{/useResponseEntity}}
{{#vendorExtensions.x-operation-extra-annotation}}
{{{.}}}
{{/vendorExtensions.x-operation-extra-annotation}}
{{#vendorExtensions.x-sse}}@ResponseBody{{/vendorExtensions.x-sse}}
{{#jdk8-default-interface}}default {{/jdk8-default-interface}}{{>responseType}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}(
{{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}}{{^-last}},
{{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}},
{{/hasParams}}{{#swagger2AnnotationLibrary}}@Parameter(hidden = true){{/swagger2AnnotationLibrary}}{{#springFoxDocumentationProvider}}@ApiIgnore{{/springFoxDocumentationProvider}} final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}},
{{/hasParams}}{{^hasParams}}{{#reactive}},{{/reactive}}{{/hasParams}}{{#springFoxDocumentationProvider}}@ApiIgnore {{/springFoxDocumentationProvider}}{{#springDocDocumentationProvider}}@ParameterObject {{/springDocDocumentationProvider}}final Pageable pageable{{/vendorExtensions.x-spring-paginated}}{{#vendorExtensions.x-spring-provide-args}}{{#hasParams}},
{{/hasParams}}{{^hasParams}}{{#reactive}},{{/reactive}}{{/hasParams}}{{#swagger2AnnotationLibrary}}@Parameter(hidden = true){{/swagger2AnnotationLibrary}}{{#springFoxDocumentationProvider}}@ApiIgnore{{/springFoxDocumentationProvider}} {{{.}}}{{^hasParams}}{{^-last}}{{^reactive}},{{/reactive}}
{{/-last}}{{/hasParams}}{{/vendorExtensions.x-spring-provide-args}}
){{#unhandledException}} throws Exception{{/unhandledException}}{{^jdk8-default-interface}};{{/jdk8-default-interface}}{{#jdk8-default-interface}} {
{{#delegate-method}} {{#delegate-method}}
return {{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, pageable{{/vendorExtensions.x-spring-paginated}}); {{^isVoid}}return {{/isVoid}}{{#isVoid}}{{#useResponseEntity}}return {{/useResponseEntity}}{{^useResponseEntity}}{{#reactive}}return {{/reactive}}{{/useResponseEntity}}{{/isVoid}}{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}}, {{/hasParams}}{{^hasParams}}{{#reactive}}, {{/reactive}}{{/hasParams}}pageable{{/vendorExtensions.x-spring-paginated}});
} }
// Override this method // Override this method
{{#jdk8-default-interface}}default {{/jdk8-default-interface}} {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{{dataType}}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#reactive}}Flux<Part>{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}} final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}} { {{#jdk8-default-interface}}default {{/jdk8-default-interface}} {{>responseType}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{{dataType}}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#reactive}}Flux<Part>{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}{{#springFoxDocumentationProvider}}@ApiIgnore{{/springFoxDocumentationProvider}} final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}}, {{/hasParams}}{{^hasParams}}{{#reactive}}, {{/reactive}}{{/hasParams}}{{#springFoxDocumentationProvider}}@ApiIgnore{{/springFoxDocumentationProvider}}final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}} {
{{/delegate-method}} {{/delegate-method}}
{{^isDelegate}} {{^isDelegate}}
{{>methodBody}} {{>methodBody}}
{{/isDelegate}} {{/isDelegate}}
{{#isDelegate}} {{#isDelegate}}
return getDelegate().{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, pageable{{/vendorExtensions.x-spring-paginated}}); {{^isVoid}}return {{/isVoid}}{{#isVoid}}{{#useResponseEntity}}return {{/useResponseEntity}}{{^useResponseEntity}}{{#reactive}}return {{/reactive}}{{/useResponseEntity}}{{/isVoid}}getDelegate().{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}}, {{/hasParams}}{{^hasParams}}{{#reactive}}, {{/reactive}}{{/hasParams}}pageable{{/vendorExtensions.x-spring-paginated}});
{{/isDelegate}} {{/isDelegate}}
}{{/jdk8-default-interface}} }{{/jdk8-default-interface}}

View File

@ -1,26 +1,25 @@
{{{ vendorExtensions.x-constraints }}} {{{ vendorExtensions.x-constraints }}}
{{#errorMessage}}@Mandatory(errorMessage="{{{pattern}}}") {{/errorMessage}} {{#pattern}}{{^isByteArray}}@Pattern(regexp = "{{{pattern}}}"{{#vendorExtensions.x-pattern-message}}, message="{{vendorExtensions.x-pattern-message}}"{{/vendorExtensions.x-pattern-message}}) {{/isByteArray}}{{/pattern}}{{!
{{#pattern}}@Pattern(regexp="{{{pattern}}}") {{/pattern}}{{!
minLength && maxLength set minLength && maxLength set
}}{{#minLength}}{{#maxLength}}@Size(min = {{minLength}}, max = {{maxLength}}) {{/maxLength}}{{/minLength}}{{! }}{{#minLength}}{{#maxLength}}@Size(min = {{minLength}}, max = {{maxLength}}) {{/maxLength}}{{/minLength}}{{!
minLength set, maxLength not minLength set, maxLength not
}}{{#minLength}}{{^maxLength}}@Size(min = {{minLength}}) {{/maxLength}}{{/minLength}}{{! }}{{#minLength}}{{^maxLength}}@Size(min = {{minLength}}) {{/maxLength}}{{/minLength}}{{!
minLength not set, maxLength set minLength not set, maxLength set
}}{{^minLength}}{{#maxLength}}@Size(max={{maxLength}}) {{/maxLength}}{{/minLength}}{{! }}{{^minLength}}{{#maxLength}}@Size(max = {{.}}) {{/maxLength}}{{/minLength}}{{!
@Size: minItems && maxItems set @Size: minItems && maxItems set
}}{{#minItems}}{{#maxItems}}@Size(min = {{minItems}}, max = {{maxItems}}) {{/maxItems}}{{/minItems}}{{! }}{{#minItems}}{{#maxItems}}@Size(min = {{minItems}}, max = {{maxItems}}) {{/maxItems}}{{/minItems}}{{!
@Size: minItems set, maxItems not @Size: minItems set, maxItems not
}}{{#minItems}}{{^maxItems}}@Size(min = {{minItems}}) {{/maxItems}}{{/minItems}}{{! }}{{#minItems}}{{^maxItems}}@Size(min = {{minItems}}) {{/maxItems}}{{/minItems}}{{!
@Size: minItems not set && maxItems set @Size: minItems not set && maxItems set
}}{{^minItems}}{{#maxItems}}@Size(max={{maxItems}}) {{/maxItems}}{{/minItems}}{{! }}{{^minItems}}{{#maxItems}}@Size(max = {{.}}) {{/maxItems}}{{/minItems}}{{!
@Email: useBeanValidation set && isEmail && java8 set @Email: useBeanValidation
}}{{#useBeanValidation}}{{#isEmail}}{{#java8}}@javax.validation.constraints.Email{{/java8}}{{/isEmail}}{{/useBeanValidation}}{{! }}{{#isEmail}}{{#useBeanValidation}}@{{javaxPackage}}.validation.constraints.Email {{/useBeanValidation}}{{!
@Email: performBeanValidation set && isEmail && not java8 set @Email: performBeanValidation exclusive
}}{{#performBeanValidation}}{{#isEmail}}{{^java8}}@org.hibernate.validator.constraints.Email{{/java8}}{{/isEmail}}{{/performBeanValidation}}{{! }}{{^useBeanValidation}}{{#performBeanValidation}}@org.hibernate.validator.constraints.Email {{/performBeanValidation}}{{/useBeanValidation}}{{/isEmail}}{{!
check for integer or long / all others=decimal type with @Decimal* check for integer or long / all others=decimal type with @Decimal*
isInteger set isInteger set
}}{{#isInteger}}{{#minimum}}@Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}) {{/maximum}}{{/isInteger}}{{! }}{{#isInteger}}{{#minimum}}@Min({{.}}) {{/minimum}}{{#maximum}}@Max({{.}}) {{/maximum}}{{/isInteger}}{{!
isLong set isLong set
}}{{#isLong}}{{#minimum}}@Min({{minimum}}L){{/minimum}}{{#maximum}} @Max({{maximum}}L) {{/maximum}}{{/isLong}}{{! }}{{#isLong}}{{#minimum}}@Min({{.}}L) {{/minimum}}{{#maximum}}@Max({{.}}L) {{/maximum}}{{/isLong}}{{!
Not Integer, not Long => we have a decimal value! Not Integer, not Long => we have a decimal value!
}}{{^isInteger}}{{^isLong}}{{#minimum}}@DecimalMin({{#exclusiveMinimum}}value = {{/exclusiveMinimum}}"{{minimum}}"{{#exclusiveMinimum}}, inclusive = false{{/exclusiveMinimum}}) {{/minimum}}{{#maximum}}@DecimalMax({{#exclusiveMaximum}}value = {{/exclusiveMaximum}}"{{maximum}}"{{#exclusiveMaximum}}, inclusive = false{{/exclusiveMaximum}}) {{/maximum}}{{/isLong}}{{/isInteger}} }}{{^isInteger}}{{^isLong}}{{#minimum}}@DecimalMin({{#exclusiveMinimum}}value = {{/exclusiveMinimum}}"{{minimum}}"{{#exclusiveMinimum}}, inclusive = false{{/exclusiveMinimum}}) {{/minimum}}{{#maximum}}@DecimalMax({{#exclusiveMaximum}}value = {{/exclusiveMaximum}}"{{maximum}}"{{#exclusiveMaximum}}, inclusive = false{{/exclusiveMaximum}}) {{/maximum}}{{/isLong}}{{/isInteger}}

View File

@ -1 +1 @@
{{#isCookieParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}@ApiParam(value = "{{{description}}}"{{#required}},required=true{{/required}}{{#allowableValues}}, allowableValues = "{{#enumVars}}{{#lambdaEscapeDoubleQuote}}{{{value}}}{{/lambdaEscapeDoubleQuote}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/enumVars}}"{{/allowableValues}}{{^isContainer}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}{{/isContainer}}) @CookieValue("{{baseName}}") {{>optionalDataType}} {{paramName}}{{/isCookieParam}} {{#isCookieParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{>paramDoc}} @CookieValue(name = "{{baseName}}"{{^required}}, required = false{{/required}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{>dateTimeParam}} {{>optionalDataType}} {{paramName}}{{/isCookieParam}}

View File

@ -1,31 +0,0 @@
class {{classname}} {
/// The underlying value of this enum member.
{{dataType}} value;
{{classname}}._internal(this.value);
{{ vendorExtensions.x-enum-varnames }}
{{ vendorExtensions.x-enum-descriptions }}
{{#allowableValues}}
{{#enumVars}}
{{#description}}
/// {{description}}
{{/description}}
static {{classname}} {{name}} = {{classname}}._internal({{{value}}});
{{/enumVars}}
{{/allowableValues}}
{{classname}}.fromJson(dynamic data) {
switch (data) {
{{#allowableValues}}
{{#enumVars}}
case {{{value}}}: value = data; break;
{{/enumVars}}
{{/allowableValues}}
default: throw('Unknown enum value to decode: $data');
}
}
static dynamic encode({{classname}} data) {
return data.value;
}
}

View File

@ -0,0 +1,60 @@
/**
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{{description}}}
*/
{{>additionalEnumTypeAnnotations}}public enum {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} {
{{#gson}}
{{#allowableValues}}
{{#enumVars}}
{{#enumDescription}}
/**
* {{.}}
*/
{{/enumDescription}}
@SerializedName({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}
{{/enumVars}}
{{/allowableValues}}
{{/gson}}
{{^gson}}
{{#allowableValues}}
{{#enumVars}}
{{#enumDescription}}
/**
* {{.}}
*/
{{/enumDescription}}
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}
{{/enumVars}}
{{/allowableValues}}
{{/gson}}
private {{{dataType}}} value;
{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}({{{dataType}}} value) {
this.value = value;
}
{{#jackson}}
@JsonValue
{{/jackson}}
public {{{dataType}}} getValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
@JsonCreator
public static {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue({{{dataType}}} value) {
for ({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (b.value.{{^isString}}equals{{/isString}}{{#isString}}{{#useEnumCaseInsensitive}}equalsIgnoreCase{{/useEnumCaseInsensitive}}{{^useEnumCaseInsensitive}}equals{{/useEnumCaseInsensitive}}{{/isString}}(value)) {
return b;
}
}
{{#isNullable}}return null;{{/isNullable}}{{^isNullable}}throw new IllegalArgumentException("Unexpected value '" + value + "'");{{/isNullable}}
}
}

View File

@ -0,0 +1,61 @@
{{#jackson}}
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
{{/jackson}}
/**
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{{description}}}
*/
{{>additionalEnumTypeAnnotations}}
{{>generatedAnnotation}}
public enum {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} {
{{#gson}}
{{#allowableValues}}{{#enumVars}}
{{#enumDescription}}
/**
* {{.}}
*/
{{/enumDescription}}
@SerializedName({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
{{/gson}}
{{^gson}}
{{#allowableValues}}{{#enumVars}}
{{#enumDescription}}
/**
* {{.}}
*/
{{/enumDescription}}
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
{{/gson}}
private {{{dataType}}} value;
{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) {
this.value = value;
}
{{#jackson}}
@JsonValue
{{/jackson}}
public {{{dataType}}} getValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
@JsonCreator
public static {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue({{{dataType}}} value) {
for ({{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if (b.value.{{^isString}}equals{{/isString}}{{#isString}}{{#useEnumCaseInsensitive}}equalsIgnoreCase{{/useEnumCaseInsensitive}}{{^useEnumCaseInsensitive}}equals{{/useEnumCaseInsensitive}}{{/isString}}(value)) {
return b;
}
}
{{#isNullable}}return null;{{/isNullable}}{{^isNullable}}throw new IllegalArgumentException("Unexpected value '" + value + "'");{{/isNullable}}
}
}

View File

@ -1,42 +1,62 @@
package {{package}}; package {{package}};
import java.net.URI;
import java.util.Objects;
{{#imports}}import {{import}}; {{#imports}}import {{import}};
{{/imports}} {{/imports}}
import com.fasterxml.jackson.databind.annotation.*;
import com.fasterxml.jackson.annotation.*;
import com.baeldung.openapi.petstore.validation.Capitalized; import com.baeldung.openapi.petstore.validation.Capitalized;
{{^supportJava6}} {{#openApiNullable}}
import java.util.Objects; import org.openapitools.jackson.nullable.JsonNullable;
import java.util.Arrays; {{/openApiNullable}}
{{/supportJava6}}
{{#supportJava6}}
import org.apache.commons.lang3.ObjectUtils;
{{/supportJava6}}
{{#imports}}
import {{import}};
{{/imports}}
{{#serializableModel}} {{#serializableModel}}
import java.io.Serializable; import java.io.Serializable;
{{/serializableModel}} {{/serializableModel}}
import java.time.OffsetDateTime;
{{#useBeanValidation}}
import {{javaxPackage}}.validation.Valid;
import {{javaxPackage}}.validation.constraints.*;
{{/useBeanValidation}}
{{^useBeanValidation}}
import {{javaxPackage}}.validation.constraints.NotNull;
{{/useBeanValidation}}
{{#performBeanValidation}}
import org.hibernate.validator.constraints.*;
{{/performBeanValidation}}
{{#jackson}} {{#jackson}}
{{#withXml}} {{#withXml}}
import com.fasterxml.jackson.dataformat.xml.annotation.*; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
{{/withXml}} {{/withXml}}
{{/jackson}} {{/jackson}}
{{#swagger2AnnotationLibrary}}
import io.swagger.v3.oas.annotations.media.Schema;
{{/swagger2AnnotationLibrary}}
{{#withXml}} {{#withXml}}
import javax.xml.bind.annotation.*; import {{javaxPackage}}.xml.bind.annotation.*;
{{/withXml}} {{/withXml}}
{{#parcelableModel}} {{^parent}}
import android.os.Parcelable; {{#hateoas}}
import android.os.Parcel; import org.springframework.hateoas.RepresentationModel;
{{/parcelableModel}} {{/hateoas}}
{{#useBeanValidation}} {{/parent}}
import javax.validation.constraints.*;
import javax.validation.Valid; import java.util.*;
{{/useBeanValidation}} import {{javaxPackage}}.annotation.Generated;
{{#models}} {{#models}}
{{#model}} {{#model}}
{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{>pojo}}{{/isEnum}} {{#additionalPropertiesType}}
import java.util.Map;
import java.util.HashMap;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
{{/additionalPropertiesType}}
{{#isEnum}}
{{>enumOuterClass}}
{{/isEnum}}
{{^isEnum}}
{{#vendorExtensions.x-is-one-of-interface}}{{>oneof_interface}}{{/vendorExtensions.x-is-one-of-interface}}{{^vendorExtensions.x-is-one-of-interface}}{{>pojo}}{{/vendorExtensions.x-is-one-of-interface}}
{{/isEnum}}
{{/model}} {{/model}}
{{/models}} {{/models}}

View File

@ -1,68 +0,0 @@
{{#jackson}}
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
{{/jackson}}
{{#gson}}
import java.io.IOException;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
{{/gson}}
/**
* {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
*/
{{#gson}}
@JsonAdapter({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.Adapter.class)
{{/gson}}
public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} {
{{#allowableValues}}{{#enumVars}}
{{{name}}}({{{value}}}){{^-last}},
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
private {{{dataType}}} value;
{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) {
this.value = value;
}
{{#jackson}}
@JsonValue
{{/jackson}}
public {{{dataType}}} getValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
{{#jackson}}
@JsonCreator
{{/jackson}}
public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue{{#jackson}}({{{dataType}}} value){{/jackson}}{{^jackson}}(String text){{/jackson}} {
for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
if ({{#jackson}}b.value.equals(value){{/jackson}}{{^jackson}}String.valueOf(b.value).equals(text){{/jackson}}) {
return b;
}
}
throw new UlpValidationException(UlpBundleKey.{{vendorExtensions.x-enum-invalidtag}});
}
{{#gson}}
public static class Adapter extends TypeAdapter<{{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}> {
@Override
public void write(final JsonWriter jsonWriter, final {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} enumeration) throws IOException {
jsonWriter.value(enumeration.getValue());
}
@Override
public {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} read(final JsonReader jsonReader) throws IOException {
{{#isNumber}}BigDecimal value = new BigDecimal(jsonReader.nextDouble()){{/isNumber}}{{^isNumber}}{{#isInteger}}Integer value {{/isInteger}}{{^isInteger}}String value {{/isInteger}}= jsonReader.{{#isInteger}}nextInt(){{/isInteger}}{{^isInteger}}nextString(){{/isInteger}}{{/isNumber}};
return {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.fromValue({{#jackson}}value{{/jackson}}{{^jackson}}String.valueOf(value){{/jackson}});
}
}
{{/gson}}
}

View File

@ -0,0 +1,7 @@
{
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
"spaces": 2,
"generator-cli": {
"version": "7.2.0"
}
}

View File

@ -8,4 +8,5 @@ This module contains articles about Spring with Thymeleaf
- [Iteration in Thymeleaf](https://www.baeldung.com/thymeleaf-iteration) - [Iteration in Thymeleaf](https://www.baeldung.com/thymeleaf-iteration)
- [Spring with Thymeleaf Pagination for a List](https://www.baeldung.com/spring-thymeleaf-pagination) - [Spring with Thymeleaf Pagination for a List](https://www.baeldung.com/spring-thymeleaf-pagination)
- [Display Image With Thymeleaf](https://www.baeldung.com/spring-thymeleaf-image) - [Display Image With Thymeleaf](https://www.baeldung.com/spring-thymeleaf-image)
- [How to Check if a Variable Is Defined in Thymeleaf](https://www.baeldung.com/spring-thymeleaf-variable-defined)
- More articles: [[<-- prev]](../spring-thymeleaf-4) - More articles: [[<-- prev]](../spring-thymeleaf-4)

View File

@ -75,6 +75,16 @@
<build> <build>
<finalName>spring-testing</finalName> <finalName>spring-testing</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>15</source>
<target>15</target>
</configuration>
</plugin>
</plugins>
<resources> <resources>
<resource> <resource>
<directory>src/main/resources</directory> <directory>src/main/resources</directory>
@ -87,7 +97,7 @@
<!-- testing --> <!-- testing -->
<java-hamcrest.version>2.0.0.0</java-hamcrest.version> <java-hamcrest.version>2.0.0.0</java-hamcrest.version>
<awaitility.version>3.1.6</awaitility.version> <awaitility.version>3.1.6</awaitility.version>
<spring.version>5.3.4</spring.version> <spring.version>6.1.3</spring.version>
<javax.persistence.version>2.1.1</javax.persistence.version> <javax.persistence.version>2.1.1</javax.persistence.version>
</properties> </properties>

View File

@ -9,7 +9,14 @@ public class ClassUsingProperty {
@Value("${baeldung.testpropertysource.one}") @Value("${baeldung.testpropertysource.one}")
private String propertyOne; private String propertyOne;
@Value("${baeldung.testpropertysource.two}")
private String propertyTwo;
public String retrievePropertyOne() { public String retrievePropertyOne() {
return propertyOne; return propertyOne;
} }
public String retrievePropertyTwo() {
return propertyTwo;
}
} }

View File

@ -0,0 +1,38 @@
package com.baeldung.testpropertysource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = ClassUsingProperty.class)
@TestPropertySource(
locations = "/other-location.properties",
properties = {
"baeldung.testpropertysource.one=one",
"baeldung.testpropertysource.two=two",
})
public class MultiplePropertiesInPropertySourceListIntegrationTest {
@Autowired
ClassUsingProperty classUsingProperty;
@Test
public void givenAMultilinePropertySource_whenVariableOneRetrieved_thenValueInPropertyAnnotationIsReturned() {
String output = classUsingProperty.retrievePropertyOne();
assertThat(output).isEqualTo("one");
}
@Test
public void givenAMultilinePropertySource_whenVariableTwoRetrieved_thenValueInPropertyAnnotationIsReturned() {
String output = classUsingProperty.retrievePropertyTwo();
assertThat(output).isEqualTo("two");
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.testpropertysource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = ClassUsingProperty.class)
@TestPropertySource(
locations = "/other-location.properties",
properties = """
baeldung.testpropertysource.one=one
baeldung.testpropertysource.two=two
""")
public class MultiplePropertiesInPropertySourceTextBlockIntegrationTest {
@Autowired
ClassUsingProperty classUsingProperty;
@Test
public void givenAMultilinePropertySource_whenVariableOneRetrieved_thenValueInPropertyAnnotationIsReturned() {
String output = classUsingProperty.retrievePropertyOne();
assertThat(output).isEqualTo("one");
}
@Test
public void givenAMultilinePropertySource_whenVariableTwoRetrieved_thenValueInPropertyAnnotationIsReturned() {
String output = classUsingProperty.retrievePropertyTwo();
assertThat(output).isEqualTo("two");
}
}

View File

@ -18,7 +18,7 @@ public class PropertiesTestPropertySourceIntegrationTest {
ClassUsingProperty classUsingProperty; ClassUsingProperty classUsingProperty;
@Test @Test
public void givenDefaultTestPropertySource_whenVariableOneRetrieved_thenValueInDefaultFileReturned() { public void givenACustomPropertySource_whenVariableOneRetrieved_thenValueInPropertyAnnotationIsReturned() {
String output = classUsingProperty.retrievePropertyOne(); String output = classUsingProperty.retrievePropertyOne();
assertThat(output).isEqualTo("other-properties-value"); assertThat(output).isEqualTo("other-properties-value");