diff --git a/apache-httpclient4/src/main/java/com/baeldung/filter/CustomWebSecurityConfigurerAdapter.java b/apache-httpclient4/src/main/java/com/baeldung/filter/CustomWebSecurityConfigurerAdapter.java index fb597e46c8..eaf166a091 100644 --- a/apache-httpclient4/src/main/java/com/baeldung/filter/CustomWebSecurityConfigurerAdapter.java +++ b/apache-httpclient4/src/main/java/com/baeldung/filter/CustomWebSecurityConfigurerAdapter.java @@ -7,14 +7,14 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; @Configuration @EnableWebSecurity -public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { +public class CustomWebSecurityConfigurerAdapter { @Autowired private RestAuthenticationEntryPoint authenticationEntryPoint; @@ -27,8 +27,8 @@ public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAda .authorities("ROLE_USER"); } - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/securityNone") @@ -40,6 +40,8 @@ public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAda .authenticationEntryPoint(authenticationEntryPoint); http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class); + + return http.build(); } @Bean diff --git a/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/ByteToCharArrayUnitTest.java b/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/ByteToCharArrayUnitTest.java new file mode 100644 index 0000000000..c62520cedc --- /dev/null +++ b/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/ByteToCharArrayUnitTest.java @@ -0,0 +1,47 @@ +package com.baeldung.array.conversions; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.assertArrayEquals; + +public class ByteToCharArrayUnitTest { + public static byte[] byteArray = {65, 66, 67, 68}; + public static char[] expected = {'A', 'B', 'C', 'D'}; + + @Test + public void givenByteArray_WhenUsingStandardCharsets_thenConvertToCharArray() { + char[] charArray = new String(byteArray, StandardCharsets.UTF_8).toCharArray(); + assertArrayEquals(expected, charArray); + } + + @Test + public void givenByteArray_WhenUsingSUsingStreams_thenConvertToCharArray() throws IOException { + ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArray); + InputStreamReader reader = new InputStreamReader(inputStream); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + int data; + while ((data = reader.read()) != -1) { + char ch = (char) data; + outputStream.write(ch); + } + char[] charArray = outputStream.toString().toCharArray(); + assertArrayEquals(expected, charArray); + } + + @Test + public void givenByteArray_WhenUsingCharBuffer_thenConvertToCharArray() { + ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray); + CharBuffer charBuffer = StandardCharsets.UTF_8.decode(byteBuffer); + char[] charArray = new char[charBuffer.remaining()]; + charBuffer.get(charArray); + assertArrayEquals(expected, charArray); + } +} diff --git a/core-java-modules/core-java-collections-maps-7/pom.xml b/core-java-modules/core-java-collections-maps-7/pom.xml index a05b1b3528..2d08c0a438 100644 --- a/core-java-modules/core-java-collections-maps-7/pom.xml +++ b/core-java-modules/core-java-collections-maps-7/pom.xml @@ -38,6 +38,16 @@ guava 32.1.2-jre + + org.openjdk.jmh + jmh-core + 1.37 + + + org.openjdk.jmh + jmh-generator-annprocess + 1.37 + diff --git a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/incrementmapkey/BenchmarkMapMethods.java similarity index 99% rename from core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java rename to core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/incrementmapkey/BenchmarkMapMethods.java index eca028efe4..563b2ffdae 100644 --- a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java +++ b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/incrementmapkey/BenchmarkMapMethods.java @@ -1,4 +1,4 @@ -package com.baeldung.map; +package com.baeldung.map.incrementmapkey; import java.util.HashMap; import java.util.Map; diff --git a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/incrementmapkey/BenchmarkMapMethodsJMH.java b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/incrementmapkey/BenchmarkMapMethodsJMH.java new file mode 100644 index 0000000000..4ddf3886e9 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/incrementmapkey/BenchmarkMapMethodsJMH.java @@ -0,0 +1,68 @@ +package com.baeldung.map.incrementmapkey; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +@State(Scope.Benchmark) +public class BenchmarkMapMethodsJMH { + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @Fork(value = 1, warmups = 1) + public void benchMarkGuavaMap() { + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingAtomicMap(getString()); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @Fork(value = 1, warmups = 1) + public void benchContainsKeyMap() { + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingContainsKey(getString()); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @Fork(value = 1, warmups = 1) + public void benchMarkComputeMethod() { + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingCompute(getString()); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + @Fork(value = 1, warmups = 1) + public void benchMarkMergeMethod() { + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingMerge(getString()); + } + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } + + private String getString() { + return + "Once upon a time in a quaint village nestled between rolling hills and whispering forests, there lived a solitary storyteller named Elias. Elias was known for spinning tales that transported listeners to magical realms and awakened forgotten dreams.\n" + + "\n" + + "His favorite spot was beneath an ancient oak tree, its sprawling branches offering shade to those who sought refuge from the bustle of daily life. Villagers of all ages would gather around Elias, their faces illuminated by the warmth of his stories.\n" + + "\n" + "One evening, as dusk painted the sky in hues of orange and purple, a curious young girl named Lily approached Elias. Her eyes sparkled with wonder as she asked for a tale unlike any other.\n" + "\n" + + "Elias smiled, sensing her thirst for adventure, and began a story about a forgotten kingdom veiled by mist, guarded by mystical creatures and enchanted by ancient spells. With each word, the air grew thick with anticipation, and the listeners were transported into a world where magic danced on the edges of reality.\n" + + "\n" + "As Elias weaved the story, Lily's imagination took flight. She envisioned herself as a brave warrior, wielding a shimmering sword against dark forces, her heart fueled by courage and kindness.\n" + "\n" + + "The night wore on, but the spell of the tale held everyone captive. The villagers laughed, gasped, and held their breaths, journeying alongside the characters through trials and triumphs.\n" + "\n" + + "As the final words lingered in the air, a sense of enchantment settled upon the listeners. They thanked Elias for the gift of his storytelling, each carrying a piece of the magical kingdom within their hearts.\n" + "\n" + + "Lily, inspired by the story, vowed to cherish the spirit of adventure and kindness in her own life. With a newfound spark in her eyes, she bid Elias goodnight, already dreaming of the countless adventures awaiting her.\n" + "\n" + + "Under the star-studded sky, Elias remained beneath the ancient oak, his heart aglow with the joy of sharing tales that ignited imagination and inspired dreams. And as the night embraced the village, whispers of the enchanted kingdom lingered in the breeze, promising endless possibilities to those who dared to believe."; + } +} diff --git a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/incrementmapkey/IncrementMapValueWays.java similarity index 98% rename from core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java rename to core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/incrementmapkey/IncrementMapValueWays.java index 70b3c6c54d..e15b3aae8e 100644 --- a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java +++ b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/incrementmapkey/IncrementMapValueWays.java @@ -1,4 +1,4 @@ -package com.baeldung.map; +package com.baeldung.map.incrementmapkey; import java.util.HashMap; import java.util.Map; diff --git a/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/incrementmapkey/IncrementMapValueUnitTest.java similarity index 97% rename from core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java rename to core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/incrementmapkey/IncrementMapValueUnitTest.java index df4f2b787e..64b9e1155d 100644 --- a/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java +++ b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/incrementmapkey/IncrementMapValueUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.map; +package com.baeldung.map.incrementmapkey; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -9,6 +9,8 @@ import java.util.stream.Stream; import org.junit.Assert; import org.junit.Test; +import com.baeldung.map.incrementmapkey.IncrementMapValueWays; + public class IncrementMapValueUnitTest { @Test diff --git a/core-java-modules/core-java-concurrency-advanced-5/src/main/java/com/baeldung/wait_synchronization/ConditionChecker.java b/core-java-modules/core-java-concurrency-advanced-5/src/main/java/com/baeldung/wait_synchronization/ConditionChecker.java index dca36fe7cb..34e0a7522b 100644 --- a/core-java-modules/core-java-concurrency-advanced-5/src/main/java/com/baeldung/wait_synchronization/ConditionChecker.java +++ b/core-java-modules/core-java-concurrency-advanced-5/src/main/java/com/baeldung/wait_synchronization/ConditionChecker.java @@ -2,7 +2,7 @@ package com.baeldung.wait_synchronization; public class ConditionChecker { - private volatile Boolean jobIsDone; + private volatile boolean jobIsDone; private final Object lock = new Object(); public void ensureCondition() { @@ -21,4 +21,4 @@ public class ConditionChecker { lock.notify(); } } -} \ No newline at end of file +} diff --git a/core-java-modules/core-java-console/pom.xml b/core-java-modules/core-java-console/pom.xml index 8677b672ea..a761b2749e 100644 --- a/core-java-modules/core-java-console/pom.xml +++ b/core-java-modules/core-java-console/pom.xml @@ -159,7 +159,7 @@ - 3.0.0-M1 + 3.6.2 1.8 1.8 0.3.2 diff --git a/core-java-modules/core-java-documentation/pom.xml b/core-java-modules/core-java-documentation/pom.xml index be18af1b10..23443dd5ea 100644 --- a/core-java-modules/core-java-documentation/pom.xml +++ b/core-java-modules/core-java-documentation/pom.xml @@ -33,7 +33,7 @@ - 3.0.0-M1 + 3.6.2 1.8 1.8 diff --git a/core-java-modules/core-java-io-2/pom.xml b/core-java-modules/core-java-io-2/pom.xml index 8632748baa..830b386fe2 100644 --- a/core-java-modules/core-java-io-2/pom.xml +++ b/core-java-modules/core-java-io-2/pom.xml @@ -61,7 +61,7 @@ - 3.0.0-M1 + 3.6.2 3.3.1 diff --git a/core-java-modules/core-java-io/pom.xml b/core-java-modules/core-java-io/pom.xml index faeddafd81..93c9289fdd 100644 --- a/core-java-modules/core-java-io/pom.xml +++ b/core-java-modules/core-java-io/pom.xml @@ -134,7 +134,7 @@ - 3.5.0 + 3.6.2 2.7.1 2.8.0 diff --git a/core-java-modules/core-java-jar/pom.xml b/core-java-modules/core-java-jar/pom.xml index a46299c669..138827781e 100644 --- a/core-java-modules/core-java-jar/pom.xml +++ b/core-java-modules/core-java-jar/pom.xml @@ -274,7 +274,7 @@ 4.6.1 1.1 - 3.0.0-M1 + 3.6.2 1.4.4 3.1.1 3.3.0 diff --git a/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/negate/NegateIntUnitTest.java b/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/negate/NegateIntUnitTest.java new file mode 100644 index 0000000000..444f4931d3 --- /dev/null +++ b/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/negate/NegateIntUnitTest.java @@ -0,0 +1,69 @@ +package com.baeldung.negate; + +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.jupiter.api.Assertions.*; + +public class NegateIntUnitTest { + + private static final Logger LOG = LoggerFactory.getLogger(NegateIntUnitTest.class); + + @Test + void whenUsingUnaryMinusOperator_thenGetExpectedResult() { + int x = 42; + assertEquals(-42, -x); + + int z = 0; + assertEquals(0, -z); + + int n = -42; + assertEquals(42, -n); + } + + @Test + void whenUsingBitwiseComplementOperator_thenGetExpectedResult() { + int x = 42; + assertEquals(-42, ~x + 1); + + int z = 0; + assertEquals(0, ~z + 1); + + int n = -42; + assertEquals(42, ~n + 1); + } + + @Test + void givenIntMinValue_whenUsingUnaryMinusOperator_thenCannotGetExpectedResult() { + int min = Integer.MIN_VALUE; + LOG.info("The value of '-min' is: " + -min); + + assertTrue((-min) < 0); + } + + @Test + void givenIntMinValue_whenUsingBitwiseComplementOperator_thenCannotGetExpectedResult() { + int min = Integer.MIN_VALUE; + int result = ~min + 1; + LOG.info("The value of '~min + 1' is: " + result); + + assertTrue(result < 0); + } + + + @Test + void whenUsingUnaryMinusOperatorWithMinInt_thenGetExpectedResult() { + int x = 42; + assertEquals(-42, Math.negateExact(x)); + + int z = 0; + assertEquals(0, Math.negateExact(z)); + + int n = -42; + assertEquals(42, Math.negateExact(n)); + + int min = Integer.MIN_VALUE; + assertThrowsExactly(ArithmeticException.class, () -> Math.negateExact(min)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-serialization/pom.xml b/core-java-modules/core-java-serialization/pom.xml index 63771d2da0..ad0a730514 100644 --- a/core-java-modules/core-java-serialization/pom.xml +++ b/core-java-modules/core-java-serialization/pom.xml @@ -177,7 +177,7 @@ 0.4 1.8.7 1.1 - 3.0.0-M1 + 3.6.2 4.3.20.RELEASE diff --git a/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringbuffer/ComparePerformance.java b/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringbuffer/ComparePerformance.java new file mode 100644 index 0000000000..28cd2e64e9 --- /dev/null +++ b/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringbuffer/ComparePerformance.java @@ -0,0 +1,63 @@ +package com.baeldung.stringbuffer; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@BenchmarkMode(Mode.SingleShotTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Measurement(batchSize = 10000, iterations = 10) +@Warmup(batchSize = 1000, iterations = 10) +@State(Scope.Thread) +public class ComparePerformance { + + String strInitial = "springframework"; + String strFinal = ""; + String replacement = "java-"; + + @Benchmark + public String benchmarkStringConcatenation() { + strFinal += strInitial; + return strFinal; + } + + @Benchmark + public StringBuffer benchmarkStringBufferConcatenation() { + StringBuffer stringBuffer = new StringBuffer(strFinal); + stringBuffer.append(strInitial); + return stringBuffer; + } + + @Benchmark + public String benchmarkStringReplacement() { + strFinal = strInitial.replaceFirst("spring", replacement); + return strFinal; + } + + @Benchmark + public StringBuffer benchmarkStringBufferReplacement() { + StringBuffer stringBuffer = new StringBuffer(strInitial); + stringBuffer.replace(0,6, replacement); + return stringBuffer; + } + + public static void main(String[] args) throws RunnerException { + Options options = new OptionsBuilder() + .include(ComparePerformance.class.getSimpleName()).threads(1) + .forks(1).shouldFailOnError(true) + .shouldDoGC(true) + .jvmArgs("-server").build(); + new Runner(options).run(); + } +} diff --git a/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringbuffer/HashCode.java b/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringbuffer/HashCode.java new file mode 100644 index 0000000000..65f17263a9 --- /dev/null +++ b/core-java-modules/core-java-strings/src/main/java/com/baeldung/stringbuffer/HashCode.java @@ -0,0 +1,24 @@ +package com.baeldung.stringbuffer; + +public class HashCode { + + public static long getHashCodeString(String string) { + return string.hashCode(); + } + + public static long getHashCodeSBuffer(StringBuffer strBuff) { + return strBuff.hashCode(); + } + + public static void main(String[] args) { + String str = "Spring"; + System.out.println("String HashCode pre concatenation :" + getHashCodeString(str)); + str += "Framework"; + System.out.println("String HashCode post concatenation :" + getHashCodeString(str)); + + StringBuffer sBuf = new StringBuffer("Spring"); + System.out.println("StringBuffer HashCode pre concatenation :" + getHashCodeSBuffer(sBuf)); + sBuf.append("Framework"); + System.out.println("StringBuffer HashCode post concatenation :" + getHashCodeSBuffer(sBuf)); + } +} diff --git a/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringIterator/StringIteratorTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringIterator/StringIteratorTest.java index 585d65d4be..aef7f81da2 100644 --- a/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringIterator/StringIteratorTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringIterator/StringIteratorTest.java @@ -17,7 +17,7 @@ public class StringIteratorTest { public void whenUseJavaForLoop_thenIterate() { String input = "Hello, Baeldung!"; String expectedOutput = "Hello, Baeldung!"; - String result = StringIterator.javaForLoop(input); + String result = StringIterator.javaforLoop(input); assertEquals(expectedOutput, result); } @@ -25,7 +25,7 @@ public class StringIteratorTest { public void whenUseForEachMethod_thenIterate() { String input = "Hello, Baeldung!"; String expectedOutput = "Hello, Baeldung!"; - String result = StringIterator.java8ForEach(input); + String result = StringIterator.java8forEach(input); assertEquals(expectedOutput, result); } diff --git a/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringbuffer/ComparePerformanceTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringbuffer/ComparePerformanceTest.java new file mode 100644 index 0000000000..696c4bae6b --- /dev/null +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringbuffer/ComparePerformanceTest.java @@ -0,0 +1,32 @@ +package com.baeldung.stringbuffer; + +import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; + + +public class ComparePerformanceTest { + + ComparePerformance cp = new ComparePerformance(); + + @Test + public void whenStringConcatenated_thenResultAsExpected() { + assertThat(cp.benchmarkStringConcatenation()).isEqualTo("springframework"); + } + + @Test + public void whenStringBufferConcatenated_thenResultAsExpected() { + StringBuffer stringBuffer = new StringBuffer("springframework"); + assertThat(cp.benchmarkStringBufferConcatenation()).isEqualToIgnoringCase(stringBuffer); + } + + @Test + public void whenStringReplaced_thenResultAsExpected() { + assertThat(cp.benchmarkStringReplacement()).isEqualTo("java-framework"); + } + + @Test + public void whenStringBufferReplaced_thenResultAsExpected() { + StringBuffer stringBuffer = new StringBuffer("java-framework"); + assertThat(cp.benchmarkStringBufferReplacement()).isEqualToIgnoringCase(stringBuffer); + } +} diff --git a/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringbuffer/HashCodeTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringbuffer/HashCodeTest.java new file mode 100644 index 0000000000..265c4e1e40 --- /dev/null +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringbuffer/HashCodeTest.java @@ -0,0 +1,24 @@ +package com.baeldung.stringbuffer; + +import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; + +public class HashCodeTest { + + String str = "Spring"; + StringBuffer sBuf = new StringBuffer("Spring"); + + @Test + public void whenStringConcat_thenHashCodeChanges() { + HashCode hc = new HashCode(); + + long initialStringHashCode = hc.getHashCodeString(str); + long initialSBufHashCode = hc.getHashCodeSBuffer(sBuf); + + str += "Framework"; + sBuf.append("Framework"); + + assertThat(initialStringHashCode).isNotEqualTo(hc.getHashCodeString(str)); + assertThat(initialSBufHashCode).isEqualTo(hc.getHashCodeSBuffer(sBuf)); + } +} diff --git a/core-java-modules/core-java-uuid/pom.xml b/core-java-modules/core-java-uuid/pom.xml index d46fcd8a65..0a0835ca46 100644 --- a/core-java-modules/core-java-uuid/pom.xml +++ b/core-java-modules/core-java-uuid/pom.xml @@ -154,7 +154,7 @@ - 3.0.0-M1 + 3.6.2 diff --git a/core-java-modules/core-java-uuid/src/main/java/com/baeldung/uuid/UUIDPositiveLongGenerator.java b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/uuid/UUIDPositiveLongGenerator.java new file mode 100644 index 0000000000..eb3a511256 --- /dev/null +++ b/core-java-modules/core-java-uuid/src/main/java/com/baeldung/uuid/UUIDPositiveLongGenerator.java @@ -0,0 +1,83 @@ +package com.baeldung.uuid; + +import java.nio.ByteBuffer; +import java.security.SecureRandom; +import java.util.UUID; + +/** + * Methods are called by reflection in the unit test + */ +@SuppressWarnings("unused") +public class UUIDPositiveLongGenerator { + public long getLeastSignificantBits() { + return Math.abs(UUID.randomUUID().getLeastSignificantBits()); + } + + public long getMostSignificantBits() { + return Math.abs(UUID.randomUUID().getMostSignificantBits()); + } + + public long combineByteBuffer() { + UUID uuid = UUID.randomUUID(); + ByteBuffer bb = ByteBuffer.wrap(new byte[16]); + bb.putLong(uuid.getMostSignificantBits()); + bb.putLong(uuid.getLeastSignificantBits()); + bb.rewind(); + return Math.abs(bb.getLong()); + } + + public long combineBitwise() { + UUID uniqueUUID = UUID.randomUUID(); + long mostSignificantBits = uniqueUUID.getMostSignificantBits(); + long leastSignificantBits = uniqueUUID.getLeastSignificantBits(); + return Math.abs((mostSignificantBits << 32) | (leastSignificantBits & 0xFFFFFFFFL)); + } + + public long combineDirect() { + UUID uniqueUUID = UUID.randomUUID(); + long mostSignificantBits = uniqueUUID.getMostSignificantBits(); + long leastSignificantBits = uniqueUUID.getLeastSignificantBits(); + return Math.abs(mostSignificantBits ^ (leastSignificantBits >> 1)); + } + + public long combinePermutation() { + UUID uuid = UUID.randomUUID(); + long mostSigBits = uuid.getMostSignificantBits(); + long leastSigBits = uuid.getLeastSignificantBits(); + byte[] uuidBytes = new byte[16]; + + for (int i = 0; i < 8; i++) { + uuidBytes[i] = (byte) (mostSigBits >>> (8 * (7 - i))); + uuidBytes[i + 8] = (byte) (leastSigBits >>> (8 * (7 - i))); + } + + long result = 0; + for (byte b : uuidBytes) { + result = (result << 8) | (b & 0xFF); + } + return Math.abs(result); + } + + public long combineWithSecureRandom() { + UUID uniqueUUID = UUID.randomUUID(); + SecureRandom secureRandom = new SecureRandom(); + long randomBits = secureRandom.nextLong(); + + long mostSignificantBits = uniqueUUID.getMostSignificantBits() ^ randomBits; + long leastSignificantBits = uniqueUUID.getLeastSignificantBits(); + + return Math.abs((mostSignificantBits << 32) | (leastSignificantBits & 0xFFFFFFFFL)); + } + + public long combineWithNanoTime() { + UUID uniqueUUID = UUID.randomUUID(); + long nanoTime = System.nanoTime(); + + long mostSignificantBits = uniqueUUID.getMostSignificantBits() ^ nanoTime; + long leastSignificantBits = uniqueUUID.getLeastSignificantBits(); + + return Math.abs((mostSignificantBits << 32) | (leastSignificantBits & 0xFFFFFFFFL)); + } + + +} diff --git a/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDPositiveLongGeneratorUnitTest.java b/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDPositiveLongGeneratorUnitTest.java new file mode 100644 index 0000000000..a4d57b19c2 --- /dev/null +++ b/core-java-modules/core-java-uuid/src/test/java/com/baeldung/uuid/UUIDPositiveLongGeneratorUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.uuid; + +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Method; +import java.util.HashSet; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +public class UUIDPositiveLongGeneratorUnitTest { + + private final UUIDPositiveLongGenerator uuidLongGenerator = new UUIDPositiveLongGenerator(); + + private final Set uniqueValues = new HashSet<>(); + + @Test + void whenForeachMethods_thenRetryWhileNotUnique() throws Exception { + for (Method method : uuidLongGenerator.getClass().getDeclaredMethods()) { + long uniqueValue; + do uniqueValue = (long) method.invoke(uuidLongGenerator); while (!isUnique(uniqueValue)); + assertThat(uniqueValue).isPositive(); + } + } + + @Test + void whenGivenLongValue_thenCheckUniqueness() { + long uniqueValue = generateUniqueLong(); + assertThat(uniqueValue).isPositive(); + } + + private long generateUniqueLong() { + long uniqueValue; + do uniqueValue = uuidLongGenerator.combineBitwise(); while (!isUnique(uniqueValue)); + return uniqueValue; + } + + private boolean isUnique(long value) { + // Implement uniqueness checking logic, for example, by checking in the database + return uniqueValues.add(value); + } + +} diff --git a/core-java-modules/core-java-uuid/src/test/resources/logback.xml b/core-java-modules/core-java-uuid/src/test/resources/logback.xml index 56af2d397e..a076f8db47 100644 --- a/core-java-modules/core-java-uuid/src/test/resources/logback.xml +++ b/core-java-modules/core-java-uuid/src/test/resources/logback.xml @@ -2,8 +2,7 @@ - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/feign/pom.xml b/feign/pom.xml index edb55e7da5..127f6c490c 100644 --- a/feign/pom.xml +++ b/feign/pom.xml @@ -74,6 +74,17 @@ ${wire.mock.version} test + + jakarta.xml.bind + jakarta.xml.bind-api + 4.0.0 + + + com.sun.xml.bind + jaxb-impl + 4.0.0 + runtime + @@ -85,7 +96,7 @@ org.codehaus.mojo jaxb2-maven-plugin - 2.5.0 + 3.1.0 xjc @@ -131,6 +142,7 @@ 3.8.0 3.1.2 2.33.2 + 4.0.0 \ No newline at end of file diff --git a/jmeter/src/main/java/com/baeldung/configuration/WebSecurityConfiguration.java b/jmeter/src/main/java/com/baeldung/configuration/WebSecurityConfiguration.java index 8700dc3df4..033281e07f 100644 --- a/jmeter/src/main/java/com/baeldung/configuration/WebSecurityConfiguration.java +++ b/jmeter/src/main/java/com/baeldung/configuration/WebSecurityConfiguration.java @@ -1,52 +1,44 @@ package com.baeldung.configuration; +import java.util.HashSet; +import java.util.Set; + +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; @Configuration -public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { +public class WebSecurityConfiguration { - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - + @Bean + public InMemoryUserDetailsManager userDetailsService() { PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); - - auth.inMemoryAuthentication() - .withUser("admin").password(encoder.encode("admin")).roles("USER", "ADMIN") - .and() - .withUser("user1").password(encoder.encode("password1")).roles("USER") - .and() - .withUser("user2").password(encoder.encode("password2")).roles("USER") - .and() - .withUser("user3").password(encoder.encode("password3")).roles("USER") - .and() - .withUser("user4").password(encoder.encode("password4")).roles("USER") - .and() - .withUser("user5").password(encoder.encode("password5")).roles("USER") - .and() - .withUser("user6").password(encoder.encode("password6")).roles("USER") - .and() - .withUser("user7").password(encoder.encode("password7")).roles("USER") - .and() - .withUser("user8").password(encoder.encode("password8")).roles("USER") - .and() - .withUser("user9").password(encoder.encode("password9")).roles("USER") - .and() - .withUser("user10").password(encoder.encode("password10")).roles("USER"); + + Set users = new HashSet<>(); + users.add(User.withUsername("admin").password(encoder.encode("admin")).roles("USER", "ADMIN").build()); + for(int i=1;i<=10;i++){ + users.add(User.withUsername("user"+i).password(encoder.encode("password")+i).roles("USER").build()); + } + + return new InMemoryUserDetailsManager(users); } - @Override - protected void configure(HttpSecurity http) throws Exception { - + @Bean + public SecurityFilterChain securityFilter(HttpSecurity http) throws Exception { + http .authorizeRequests() .antMatchers("/secured/**").authenticated() .anyRequest().permitAll() .and() .httpBasic(); + + return http.build(); } } diff --git a/performance-tests/pom.xml b/performance-tests/pom.xml index d22a9cf3ac..7927c518f9 100644 --- a/performance-tests/pom.xml +++ b/performance-tests/pom.xml @@ -164,7 +164,7 @@ 3.2.4 3.0.0-M1 3.2.0 - 3.2.0 + 3.6.2 3.1.0 3.9.1 3.2.1 diff --git a/atomikos/README.md b/persistence-modules/atomikos/README.md similarity index 100% rename from atomikos/README.md rename to persistence-modules/atomikos/README.md diff --git a/atomikos/pom.xml b/persistence-modules/atomikos/pom.xml similarity index 98% rename from atomikos/pom.xml rename to persistence-modules/atomikos/pom.xml index 2cbc106268..c1748f7dac 100644 --- a/atomikos/pom.xml +++ b/persistence-modules/atomikos/pom.xml @@ -8,7 +8,7 @@ com.baeldung - parent-modules + persistence-modules 1.0.0-SNAPSHOT diff --git a/atomikos/src/main/java/com/baeldung/atomikos/direct/Application.java b/persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/direct/Application.java similarity index 100% rename from atomikos/src/main/java/com/baeldung/atomikos/direct/Application.java rename to persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/direct/Application.java diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/Application.java b/persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/Application.java similarity index 100% rename from atomikos/src/main/java/com/baeldung/atomikos/spring/Application.java rename to persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/Application.java diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/config/Config.java b/persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/config/Config.java similarity index 100% rename from atomikos/src/main/java/com/baeldung/atomikos/spring/config/Config.java rename to persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/config/Config.java diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/Application.java b/persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/Application.java similarity index 100% rename from atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/Application.java rename to persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/Application.java diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/config/Config.java b/persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/config/Config.java similarity index 100% rename from atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/config/Config.java rename to persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/config/Config.java diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/inventory/Inventory.java b/persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/inventory/Inventory.java similarity index 100% rename from atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/inventory/Inventory.java rename to persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/inventory/Inventory.java diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/inventory/InventoryConfig.java b/persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/inventory/InventoryConfig.java similarity index 100% rename from atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/inventory/InventoryConfig.java rename to persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/inventory/InventoryConfig.java diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/inventory/InventoryRepository.java b/persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/inventory/InventoryRepository.java similarity index 100% rename from atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/inventory/InventoryRepository.java rename to persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/inventory/InventoryRepository.java diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/Order.java b/persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/Order.java similarity index 100% rename from atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/Order.java rename to persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/Order.java diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/OrderConfig.java b/persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/OrderConfig.java similarity index 100% rename from atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/OrderConfig.java rename to persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/OrderConfig.java diff --git a/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/OrderRepository.java b/persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/OrderRepository.java similarity index 100% rename from atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/OrderRepository.java rename to persistence-modules/atomikos/src/main/java/com/baeldung/atomikos/spring/jpa/order/OrderRepository.java diff --git a/atomikos/src/main/resources/logback.xml b/persistence-modules/atomikos/src/main/resources/logback.xml similarity index 100% rename from atomikos/src/main/resources/logback.xml rename to persistence-modules/atomikos/src/main/resources/logback.xml diff --git a/atomikos/src/main/resources/schema.sql b/persistence-modules/atomikos/src/main/resources/schema.sql similarity index 100% rename from atomikos/src/main/resources/schema.sql rename to persistence-modules/atomikos/src/main/resources/schema.sql diff --git a/atomikos/src/main/resources/transactions.properties b/persistence-modules/atomikos/src/main/resources/transactions.properties similarity index 100% rename from atomikos/src/main/resources/transactions.properties rename to persistence-modules/atomikos/src/main/resources/transactions.properties diff --git a/atomikos/src/test/java/com/baeldung/atomikos/direct/ApplicationUnitTest.java b/persistence-modules/atomikos/src/test/java/com/baeldung/atomikos/direct/ApplicationUnitTest.java similarity index 100% rename from atomikos/src/test/java/com/baeldung/atomikos/direct/ApplicationUnitTest.java rename to persistence-modules/atomikos/src/test/java/com/baeldung/atomikos/direct/ApplicationUnitTest.java diff --git a/atomikos/src/test/java/com/baeldung/atomikos/spring/ApplicationUnitTest.java b/persistence-modules/atomikos/src/test/java/com/baeldung/atomikos/spring/ApplicationUnitTest.java similarity index 100% rename from atomikos/src/test/java/com/baeldung/atomikos/spring/ApplicationUnitTest.java rename to persistence-modules/atomikos/src/test/java/com/baeldung/atomikos/spring/ApplicationUnitTest.java diff --git a/atomikos/src/test/java/com/baeldung/atomikos/spring/jpa/ApplicationUnitTest.java b/persistence-modules/atomikos/src/test/java/com/baeldung/atomikos/spring/jpa/ApplicationUnitTest.java similarity index 100% rename from atomikos/src/test/java/com/baeldung/atomikos/spring/jpa/ApplicationUnitTest.java rename to persistence-modules/atomikos/src/test/java/com/baeldung/atomikos/spring/jpa/ApplicationUnitTest.java diff --git a/atomikos/src/test/resources/logback.xml b/persistence-modules/atomikos/src/test/resources/logback.xml similarity index 100% rename from atomikos/src/test/resources/logback.xml rename to persistence-modules/atomikos/src/test/resources/logback.xml diff --git a/atomikos/src/test/resources/transactions.properties b/persistence-modules/atomikos/src/test/resources/transactions.properties similarity index 100% rename from atomikos/src/test/resources/transactions.properties rename to persistence-modules/atomikos/src/test/resources/transactions.properties diff --git a/persistence-modules/hibernate-libraries/pom.xml b/persistence-modules/hibernate-libraries/pom.xml index 3f4da28296..d701487676 100644 --- a/persistence-modules/hibernate-libraries/pom.xml +++ b/persistence-modules/hibernate-libraries/pom.xml @@ -162,7 +162,7 @@ 1.6 2.9.7 - 5.4.14.Final + 5.6.15.Final 3.27.0-GA 2.3.1 2.0.0 diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 6823b460b2..d9ee7e358c 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -18,6 +18,7 @@ apache-bookkeeper apache-cayenne apache-derby + atomikos blaze-persistence core-java-persistence core-java-persistence-2 diff --git a/persistence-modules/spring-hibernate-5/pom.xml b/persistence-modules/spring-hibernate-5/pom.xml index e559fe1394..d3ba647af2 100644 --- a/persistence-modules/spring-hibernate-5/pom.xml +++ b/persistence-modules/spring-hibernate-5/pom.xml @@ -131,7 +131,7 @@ 1.10.6.RELEASE 4.2.1.RELEASE - 5.2.10.Final + 5.6.15.Final 5.8.2.Final 8.0.7-dmr 9.0.0.M26 diff --git a/pom.xml b/pom.xml index 551cb66688..95a6c951ce 100644 --- a/pom.xml +++ b/pom.xml @@ -701,7 +701,7 @@ apache-kafka apache-libraries-2 apache-libraries - apache-olingo + apache-olingo apache-poi-2 apache-poi-3 apache-poi @@ -710,7 +710,6 @@ apache-velocity asciidoctor asm - atomikos atomix aws-modules azure @@ -727,7 +726,7 @@ dozer drools dubbo - + feign gcp-firebase geotools google-auto-project @@ -947,7 +946,7 @@ apache-kafka apache-libraries-2 apache-libraries - apache-olingo + apache-olingo apache-poi-2 apache-poi-3 apache-poi @@ -956,7 +955,6 @@ apache-velocity asciidoctor asm - atomikos atomix aws-modules azure @@ -973,7 +971,7 @@ dozer drools dubbo - + feign gcp-firebase geotools google-auto-project diff --git a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java index 687a827448..e453f33d5e 100644 --- a/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java +++ b/security-modules/jjwt/src/main/java/io/jsonwebtoken/jjwtfun/config/WebSecurityConfig.java @@ -4,9 +4,11 @@ import io.jsonwebtoken.JwtException; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.jjwtfun.service.SecretService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.csrf.CsrfFilter; import org.springframework.security.web.csrf.CsrfToken; import org.springframework.security.web.csrf.CsrfTokenRepository; @@ -21,19 +23,19 @@ import java.io.IOException; import java.util.Arrays; @Configuration -public class WebSecurityConfig extends WebSecurityConfigurerAdapter { +public class WebSecurityConfig { @Autowired - CsrfTokenRepository jwtCsrfTokenRepository; + private CsrfTokenRepository jwtCsrfTokenRepository; @Autowired - SecretService secretService; + private SecretService secretService; // ordered so we can use binary search below - private String[] ignoreCsrfAntMatchers = { "/dynamic-builder-compress", "/dynamic-builder-general", "/dynamic-builder-specific", "/set-secrets" }; + private final String[] ignoreCsrfAntMatchers = { "/dynamic-builder-compress", "/dynamic-builder-general", "/dynamic-builder-specific", "/set-secrets" }; - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.addFilterAfter(new JwtCsrfValidatorFilter(), CsrfFilter.class) .csrf() .csrfTokenRepository(jwtCsrfTokenRepository) @@ -42,6 +44,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { .authorizeRequests() .antMatchers("/**") .permitAll(); + + return http.build(); } private class JwtCsrfValidatorFilter extends OncePerRequestFilter { diff --git a/spring-boot-modules/spring-boot-groovy/pom.xml b/spring-boot-modules/spring-boot-groovy/pom.xml index 151160bde5..677e07db2d 100644 --- a/spring-boot-modules/spring-boot-groovy/pom.xml +++ b/spring-boot-modules/spring-boot-groovy/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung.app spring-boot-groovy @@ -10,9 +10,10 @@ Spring Boot Todo Application with Groovy - com.baeldung.spring-boot-modules - spring-boot-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -25,7 +26,7 @@ spring-boot-starter-web - org.codehaus.groovy + org.apache.groovy groovy ${groovy.version} @@ -39,6 +40,11 @@ h2 runtime + + io.rest-assured + rest-assured + test + @@ -71,8 +77,8 @@ com.baeldung.springwithgroovy.SpringBootGroovyApplication - 3.0.13 - 1.9.0 + 4.0.11 + 3.0.2 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-groovy/src/main/groovy/com/baeldung/springwithgroovy/entity/Todo.groovy b/spring-boot-modules/spring-boot-groovy/src/main/groovy/com/baeldung/springwithgroovy/entity/Todo.groovy index 000d981701..31274e1f07 100644 --- a/spring-boot-modules/spring-boot-groovy/src/main/groovy/com/baeldung/springwithgroovy/entity/Todo.groovy +++ b/spring-boot-modules/spring-boot-groovy/src/main/groovy/com/baeldung/springwithgroovy/entity/Todo.groovy @@ -1,11 +1,11 @@ package com.baeldung.springwithgroovy.entity -import javax.persistence.Column -import javax.persistence.Entity -import javax.persistence.GeneratedValue -import javax.persistence.GenerationType -import javax.persistence.Id -import javax.persistence.Table +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.GeneratedValue +import jakarta.persistence.GenerationType +import jakarta.persistence.Id +import jakarta.persistence.Table @Entity @Table(name = 'todo') diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/caffeine/SecurityConfiguration.java b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/caffeine/SecurityConfiguration.java index 7f3ad7988f..e63726c926 100644 --- a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/caffeine/SecurityConfiguration.java +++ b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/caffeine/SecurityConfiguration.java @@ -1,9 +1,10 @@ package com.baeldung.caffeine; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.SecurityFilterChain; /** * Because the POM imports Spring Security, we need a simple security @@ -11,14 +12,14 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur */ @Configuration @EnableWebSecurity -public class SecurityConfiguration extends WebSecurityConfigurerAdapter { +public class SecurityConfiguration { - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain securityFilter(HttpSecurity http) throws Exception { http.csrf().disable(); - http.authorizeRequests() + return http.authorizeRequests() .antMatchers("/**") - .permitAll(); + .permitAll().and().build(); } } diff --git a/spring-boot-modules/spring-boot-mvc-5/pom.xml b/spring-boot-modules/spring-boot-mvc-5/pom.xml index a516cab049..10a58a6a59 100644 --- a/spring-boot-modules/spring-boot-mvc-5/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-5/pom.xml @@ -49,6 +49,10 @@ commons-configuration ${commons-configuration.version} + + org.springframework.boot + spring-boot-starter-aop + @@ -61,6 +65,14 @@ JAR + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + diff --git a/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/ModifyRequestApp.java b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/ModifyRequestApp.java new file mode 100644 index 0000000000..7dd937d5b8 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/ModifyRequestApp.java @@ -0,0 +1,11 @@ +package com.baeldung.modifyrequest; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = "com.baeldung.modifyrequest") +public class ModifyRequestApp { + public static void main(String[] args) { + SpringApplication.run(ModifyRequestApp.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/aop/EscapeHtmlAspect.java b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/aop/EscapeHtmlAspect.java new file mode 100644 index 0000000000..d4533dcf0b --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/aop/EscapeHtmlAspect.java @@ -0,0 +1,78 @@ +package com.baeldung.modifyrequest.aop; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.core.MethodParameter; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice; + +import java.io.*; +import java.lang.reflect.Type; +import java.nio.charset.StandardCharsets; + +@RestControllerAdvice +@Profile("aspectExample") +public class EscapeHtmlAspect implements RequestBodyAdvice { + + private static final Logger logger = LoggerFactory.getLogger(EscapeHtmlAspect.class); + + @Override + public boolean supports(MethodParameter methodParameter, Type targetType, Class> converterType) { + //Apply this to all Controllers + return true; + } + + @Override + public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, + Class> converterType) throws IOException { + logger.info("beforeBodyRead called"); + InputStream inputStream = inputMessage.getBody(); + return new HttpInputMessage() { + @Override + public InputStream getBody() throws IOException { + return new ByteArrayInputStream(escapeHtml(inputStream).getBytes(StandardCharsets.UTF_8)); + } + + @Override + public HttpHeaders getHeaders() { + return inputMessage.getHeaders(); + } + }; + } + + @Override + public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, + Class> converterType) { + // Return the modified object after reading the body + return body; + } + + @Override + public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, + Class> converterType) { + //return the original body + return body; + } + + private String escapeHtml(InputStream inputStream) throws IOException { + StringBuilder stringBuilder = new StringBuilder(); + BufferedReader bufferedReader = null; + try (inputStream) { + bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + char[] charBuffer = new char[128]; + int bytesRead = -1; + while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { + stringBuilder.append(charBuffer, 0, bytesRead); + } + } + String input = stringBuilder.toString(); + // Escape HTML characters + return input.replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">"); + } +} diff --git a/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/config/WebMvcConfiguration.java b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/config/WebMvcConfiguration.java new file mode 100644 index 0000000000..2fc1fbc310 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/config/WebMvcConfiguration.java @@ -0,0 +1,26 @@ +package com.baeldung.modifyrequest.config; + +import com.baeldung.modifyrequest.interceptor.EscapeHtmlRequestInterceptor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@Profile("interceptorExample") +public class WebMvcConfiguration implements WebMvcConfigurer { + private static final Logger logger = LoggerFactory.getLogger(WebMvcConfiguration.class); + + @Override + public void addInterceptors(InterceptorRegistry registry) { + logger.info("addInterceptors() called"); + registry.addInterceptor(new EscapeHtmlRequestInterceptor()) + .addPathPatterns("/save"); + + WebMvcConfigurer.super.addInterceptors(registry); + } +} + diff --git a/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/controller/UserController.java b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/controller/UserController.java new file mode 100644 index 0000000000..26450dd70d --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/controller/UserController.java @@ -0,0 +1,23 @@ +package com.baeldung.modifyrequest.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/") +public class UserController { + Logger logger = LoggerFactory.getLogger(UserController.class); + + @PostMapping(value = "save") + public ResponseEntity saveUser(@RequestBody String user) { + logger.info("save user info into database"); + ResponseEntity responseEntity = new ResponseEntity<>(user, HttpStatus.CREATED); + return responseEntity; + } +} diff --git a/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/filter/EscapeHtmlFilter.java b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/filter/EscapeHtmlFilter.java new file mode 100644 index 0000000000..45cad3be1c --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/filter/EscapeHtmlFilter.java @@ -0,0 +1,27 @@ +package com.baeldung.modifyrequest.filter; + +import com.baeldung.modifyrequest.requestwrapper.EscapeHtmlRequestWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Profile; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +@Component +@Order(1) +@Profile("filterExample") +public class EscapeHtmlFilter implements Filter { + Logger logger = LoggerFactory.getLogger(EscapeHtmlFilter.class); + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + logger.info("Modify the request"); + + filterChain.doFilter(new EscapeHtmlRequestWrapper((HttpServletRequest) servletRequest), servletResponse); + } +} diff --git a/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/interceptor/EscapeHtmlRequestInterceptor.java b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/interceptor/EscapeHtmlRequestInterceptor.java new file mode 100644 index 0000000000..1ad39605e5 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/interceptor/EscapeHtmlRequestInterceptor.java @@ -0,0 +1,19 @@ +package com.baeldung.modifyrequest.interceptor; + +import com.baeldung.modifyrequest.requestwrapper.EscapeHtmlRequestWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class EscapeHtmlRequestInterceptor implements HandlerInterceptor { + private static final Logger logger = LoggerFactory.getLogger(EscapeHtmlRequestInterceptor.class); + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + EscapeHtmlRequestWrapper escapeHtmlRequestWrapper = new EscapeHtmlRequestWrapper(request); + return true; + } +} diff --git a/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/requestwrapper/EscapeHtmlRequestWrapper.java b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/requestwrapper/EscapeHtmlRequestWrapper.java new file mode 100644 index 0000000000..e7b3abbc1f --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-5/src/main/java/com/baeldung/modifyrequest/requestwrapper/EscapeHtmlRequestWrapper.java @@ -0,0 +1,67 @@ +package com.baeldung.modifyrequest.requestwrapper; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.*; + +public class EscapeHtmlRequestWrapper extends HttpServletRequestWrapper { + private String body = null; + public EscapeHtmlRequestWrapper(HttpServletRequest request) throws IOException { + super(request); + this.body = this.escapeHtml(request); + } + + private String escapeHtml(HttpServletRequest request) throws IOException { + StringBuilder stringBuilder = new StringBuilder(); + BufferedReader bufferedReader = null; + try (InputStream inputStream = request.getInputStream()) { + bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + char[] charBuffer = new char[128]; + int bytesRead = -1; + while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { + stringBuilder.append(charBuffer, 0, bytesRead); + } + } + String input = stringBuilder.toString(); + // Escape HTML characters + return input.replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll("'", "'"); + } + + @Override + public ServletInputStream getInputStream() { + final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes()); + ServletInputStream servletInputStream = new ServletInputStream() { + + @Override + public int read() { + return byteArrayInputStream.read(); + } + + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener listener) { + + } + }; + return servletInputStream; + } + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(this.getInputStream())); + } +} diff --git a/spring-boot-modules/spring-boot-mvc-5/src/main/resources/modifyrequest/filter-sequence-design.puml b/spring-boot-modules/spring-boot-mvc-5/src/main/resources/modifyrequest/filter-sequence-design.puml new file mode 100644 index 0000000000..41689ac723 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-5/src/main/resources/modifyrequest/filter-sequence-design.puml @@ -0,0 +1,31 @@ +@startuml +'https://plantuml.com/sequence-diagram +skinparam sequenceMessageAlign direction +skinparam handwritten true +skinparam sequence { +ParticipantBackgroundColor beige +ParticipantPadding 50 +} + +autonumber + +Browser -[#63b175]> Filter: HTTP Request +activate Browser +activate Filter +Filter -[#63b175]> Filter: doFilter() +Filter -[#63b175]> DispatcherServlet: HTTP Request +activate DispatcherServlet + + +DispatcherServlet -[#63b175]> Controller: HTTP Request +activate Controller +Controller --[#63b175]> DispatcherServlet: HTTP Response +deactivate Controller + +DispatcherServlet --[#63b175]> Filter: HTTP Response +deactivate DispatcherServlet + +Filter --[#63b175]> Browser: HTTP Response +deactivate Filter +deactivate Browser +@enduml \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc-5/src/main/resources/modifyrequest/interceptor-sequence-design.puml b/spring-boot-modules/spring-boot-mvc-5/src/main/resources/modifyrequest/interceptor-sequence-design.puml new file mode 100644 index 0000000000..429b8182ca --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-5/src/main/resources/modifyrequest/interceptor-sequence-design.puml @@ -0,0 +1,33 @@ +@startuml +'https://plantuml.com/sequence-diagram +skinparam sequenceMessageAlign direction +skinparam handwritten true +skinparam sequence { +ParticipantBackgroundColor beige +ParticipantPadding 50 +} + +autonumber + +Browser -[#63b175]> Filter: Http Request +activate Browser +activate Filter +Filter -[#63b175]> DispatcherServlet: Http Request +activate DispatcherServlet + +DispatcherServlet -[#63b175]> Interceptor: Http Request +activate Interceptor +Interceptor -[#63b175]> Interceptor: preHandle() +Interceptor -[#63b175]> Controller: Http Request +activate Controller +Controller --[#63b175]> Interceptor: Http Response +deactivate Controller +Interceptor --[#63b175]> DispatcherServlet: Http Response +deactivate Interceptor +DispatcherServlet --[#63b175]> Filter: Http Response +deactivate DispatcherServlet + +Filter --[#63b175]> Browser: Http Response +deactivate Filter +deactivate Browser +@enduml \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc-5/src/test/java/com/baeldung/modifyrequest/EscapeHtmlAspectIntegrationTest.java b/spring-boot-modules/spring-boot-mvc-5/src/test/java/com/baeldung/modifyrequest/EscapeHtmlAspectIntegrationTest.java new file mode 100644 index 0000000000..ef18591ccb --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-5/src/test/java/com/baeldung/modifyrequest/EscapeHtmlAspectIntegrationTest.java @@ -0,0 +1,54 @@ +package com.baeldung.modifyrequest; + +import com.baeldung.modifyrequest.controller.UserController; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import java.net.URI; +import java.util.Map; + +@ExtendWith(SpringExtension.class) +@AutoConfigureMockMvc +@WebMvcTest(UserController.class) +@ActiveProfiles("aspectExample") +public class EscapeHtmlAspectIntegrationTest { + Logger logger = LoggerFactory.getLogger(EscapeHtmlAspectIntegrationTest.class); + + @Autowired + private MockMvc mockMvc; + @Test + void givenAspect_whenEscapeHtmlAspect_thenEscapeHtml() throws Exception { + + Map requestBody = Map.of( + "name", "James Cameron", + "email", "james@gmail.com" + ); + + Map expectedResponseBody = Map.of( + "name", "James Cameron", + "email", "<script>alert()</script>james@gmail.com" + ); + + ObjectMapper objectMapper = new ObjectMapper(); + + mockMvc.perform(MockMvcRequestBuilders.post(URI.create("/save")) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestBody))) + .andExpect(MockMvcResultMatchers.status() + .isCreated()) + .andExpect(MockMvcResultMatchers.content() + .json(objectMapper.writeValueAsString(expectedResponseBody))); + } +} diff --git a/spring-boot-modules/spring-boot-mvc-5/src/test/java/com/baeldung/modifyrequest/EscapeHtmlFilterIntegrationTest.java b/spring-boot-modules/spring-boot-mvc-5/src/test/java/com/baeldung/modifyrequest/EscapeHtmlFilterIntegrationTest.java new file mode 100644 index 0000000000..c813827422 --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-5/src/test/java/com/baeldung/modifyrequest/EscapeHtmlFilterIntegrationTest.java @@ -0,0 +1,51 @@ +package com.baeldung.modifyrequest; + +import com.baeldung.modifyrequest.controller.UserController; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import java.net.URI; +import java.util.Map; + +@ExtendWith(SpringExtension.class) +@AutoConfigureMockMvc +@WebMvcTest(UserController.class) +@ActiveProfiles("filterExample") +public class EscapeHtmlFilterIntegrationTest { + Logger logger = LoggerFactory.getLogger(EscapeHtmlFilterIntegrationTest.class); + + @Autowired + private MockMvc mockMvc; + @Test + void givenFilter_whenEscapeHtmlFilter_thenEscapeHtml() throws Exception { + Map requestBody = Map.of( + "name", "James Cameron", + "email", "james@gmail.com" + ); + + Map expectedResponseBody = Map.of( + "name", "James Cameron", + "email", "<script>alert()</script>james@gmail.com" + ); + + ObjectMapper objectMapper = new ObjectMapper(); + + mockMvc.perform(MockMvcRequestBuilders.post(URI.create("/save")) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestBody))).andExpect(MockMvcResultMatchers.status() + .isCreated()).andExpect(MockMvcResultMatchers.content() + .json(objectMapper.writeValueAsString(expectedResponseBody))); + } +} diff --git a/spring-boot-modules/spring-boot-mvc-5/src/test/java/com/baeldung/modifyrequest/EscapeHtmlInterceptorIntegrationTest.java b/spring-boot-modules/spring-boot-mvc-5/src/test/java/com/baeldung/modifyrequest/EscapeHtmlInterceptorIntegrationTest.java new file mode 100644 index 0000000000..9afc7f7e5a --- /dev/null +++ b/spring-boot-modules/spring-boot-mvc-5/src/test/java/com/baeldung/modifyrequest/EscapeHtmlInterceptorIntegrationTest.java @@ -0,0 +1,46 @@ +package com.baeldung.modifyrequest; + +import com.baeldung.modifyrequest.controller.UserController; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import java.net.URI; +import java.util.Map; + + +@ExtendWith(SpringExtension.class) +@AutoConfigureMockMvc +@WebMvcTest(UserController.class) +@ActiveProfiles("interceptorExample") +public class EscapeHtmlInterceptorIntegrationTest { + Logger logger = LoggerFactory.getLogger(EscapeHtmlInterceptorIntegrationTest.class); + + @Autowired + private MockMvc mockMvc; + + @Test + void givenInterceptor_whenEscapeHtmlInterceptor_thenEscapeHtml() throws Exception { + Map requestBody = Map.of( + "name", "James Cameron", + "email", "james@gmail.com" + ); + + ObjectMapper objectMapper = new ObjectMapper(); + mockMvc.perform(MockMvcRequestBuilders.post(URI.create("/save")) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestBody))).andExpect(MockMvcResultMatchers.status() + .is4xxClientError()); + } +} diff --git a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/spring/boot/management/logging/SecurityConfig.java b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/spring/boot/management/logging/SecurityConfig.java index 45cc1ebb33..6870f4e6bb 100644 --- a/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/spring/boot/management/logging/SecurityConfig.java +++ b/spring-boot-modules/spring-boot-runtime/src/main/java/com/baeldung/spring/boot/management/logging/SecurityConfig.java @@ -1,14 +1,16 @@ package com.baeldung.spring.boot.management.logging; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.SecurityFilterChain; @Configuration -public class SecurityConfig extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - http.csrf() - .ignoringAntMatchers("/actuator/**"); +public class SecurityConfig { + @Bean + public SecurityFilterChain securityFilter(HttpSecurity http) throws Exception { + return http.csrf() + .ignoringAntMatchers("/actuator/**").and() + .build(); } } diff --git a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/oauthfeign/OAuth2WebSecurityConfigurerAdapter.java b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/oauthfeign/OAuth2WebSecurityConfigurerAdapter.java index af60c3849b..6efacc03b1 100644 --- a/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/oauthfeign/OAuth2WebSecurityConfigurerAdapter.java +++ b/spring-cloud-modules/spring-cloud-openfeign/src/main/java/com/baeldung/cloud/openfeign/oauthfeign/OAuth2WebSecurityConfigurerAdapter.java @@ -1,19 +1,23 @@ package com.baeldung.cloud.openfeign.oauthfeign; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.SecurityFilterChain; @Configuration -public class OAuth2WebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { +public class OAuth2WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf() .disable() .oauth2Client(); + http .authorizeRequests().anyRequest().permitAll(); + + return http.build(); } } diff --git a/spring-di-2/pom.xml b/spring-di-2/pom.xml index 0bd6c41a8c..898dd182f1 100644 --- a/spring-di-2/pom.xml +++ b/spring-di-2/pom.xml @@ -55,9 +55,9 @@ - org.codehaus.mojo + dev.aspectj aspectj-maven-plugin - ${aspectj-plugin.version} + ${aspectj-maven-plugin.version} ${java.version} @@ -80,7 +80,7 @@ 3.1.2 - 1.14.0 + 1.13.1 2.17.1 diff --git a/spring-jinq/pom.xml b/spring-jinq/pom.xml index 14ac366e74..c1dee7fa9f 100644 --- a/spring-jinq/pom.xml +++ b/spring-jinq/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-boot-3 @@ -35,6 +35,11 @@ org.springframework spring-orm + + org.hibernate.orm + hibernate-core + ${hibernate-core.version} + org.springframework.boot @@ -58,7 +63,8 @@ - 1.8.29 + 2.0.1 + 6.4.0.Final \ No newline at end of file diff --git a/spring-jinq/src/main/java/com/baeldung/spring/jinq/config/JinqProviderConfiguration.java b/spring-jinq/src/main/java/com/baeldung/spring/jinq/config/JinqProviderConfiguration.java index 6d921045b7..01e16cf0f7 100644 --- a/spring-jinq/src/main/java/com/baeldung/spring/jinq/config/JinqProviderConfiguration.java +++ b/spring-jinq/src/main/java/com/baeldung/spring/jinq/config/JinqProviderConfiguration.java @@ -1,6 +1,6 @@ package com.baeldung.spring.jinq.config; -import javax.persistence.EntityManagerFactory; +import jakarta.persistence.EntityManagerFactory; import org.jinq.jpa.JinqJPAStreamProvider; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Car.java b/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Car.java index 263e6c7622..a0b9620629 100644 --- a/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Car.java +++ b/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Car.java @@ -1,19 +1,23 @@ package com.baeldung.spring.jinq.entities; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToOne; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; + + @Entity(name = "CAR") public class Car { + @Id private String model; private String description; private int year; private String engine; + @ManyToOne + @JoinColumn(name = "name") private Manufacturer manufacturer; - @Id public String getModel() { return model; } @@ -46,8 +50,6 @@ public class Car { this.engine = engine; } - @OneToOne - @JoinColumn(name = "name") public Manufacturer getManufacturer() { return manufacturer; } diff --git a/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Manufacturer.java b/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Manufacturer.java index f6e5fd23de..0021e45658 100644 --- a/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Manufacturer.java +++ b/spring-jinq/src/main/java/com/baeldung/spring/jinq/entities/Manufacturer.java @@ -2,18 +2,19 @@ package com.baeldung.spring.jinq.entities; import java.util.List; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.OneToMany; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; @Entity(name = "MANUFACTURER") public class Manufacturer { + @Id private String name; private String city; + @OneToMany(mappedBy = "model") private List cars; - @Id public String getName() { return name; } @@ -30,7 +31,6 @@ public class Manufacturer { this.city = city; } - @OneToMany(mappedBy = "model") public List getCars() { return cars; } @@ -38,5 +38,4 @@ public class Manufacturer { public void setCars(List cars) { this.cars = cars; } - } diff --git a/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/BaseJinqRepositoryImpl.java b/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/BaseJinqRepositoryImpl.java index 42b81ecc59..e85231f537 100644 --- a/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/BaseJinqRepositoryImpl.java +++ b/spring-jinq/src/main/java/com/baeldung/spring/jinq/repositories/BaseJinqRepositoryImpl.java @@ -1,7 +1,7 @@ package com.baeldung.spring.jinq.repositories; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import org.jinq.jpa.JPAJinqStream; import org.jinq.jpa.JinqJPAStreamProvider; diff --git a/spring-jinq/src/test/java/com/baeldung/SpringContextTest.java b/spring-jinq/src/test/java/com/baeldung/SpringContextTest.java index 1a486d1003..7c65a831c4 100644 --- a/spring-jinq/src/test/java/com/baeldung/SpringContextTest.java +++ b/spring-jinq/src/test/java/com/baeldung/SpringContextTest.java @@ -4,7 +4,6 @@ import com.baeldung.spring.jinq.JinqApplication; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import com.baeldung.spring.jinq.JinqApplication; @SpringBootTest(classes = JinqApplication.class) public class SpringContextTest { diff --git a/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml b/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml index ee2c86238a..1e3b93ae42 100644 --- a/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml +++ b/spring-swagger-codegen/spring-openapi-generator-api-client/pom.xml @@ -276,7 +276,7 @@ 2.2 1.10 3.6.1 - 2.10.4 + 3.6.2 2.2.1 1.5 diff --git a/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml b/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml index 35f4978411..af12f9cef0 100644 --- a/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml +++ b/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml @@ -196,7 +196,7 @@ 2.2 1.5 2.2.1 - 2.10.4 + 3.6.2 1.10 diff --git a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCSecurity.java b/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCSecurity.java index ea51ca3cd9..074cc20be1 100644 --- a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCSecurity.java +++ b/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCSecurity.java @@ -2,42 +2,37 @@ package com.baeldung.thymeleaf.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) -public class WebMVCSecurity extends WebSecurityConfigurerAdapter { +public class WebMVCSecurity { @Bean - @Override - public AuthenticationManager authenticationManagerBean() throws Exception { - return super.authenticationManagerBean(); + public InMemoryUserDetailsManager userDetailsService() { + UserDetails user = User.withUsername("user1") + .password("{noop}user1Pass") + .authorities("USER") + .build(); + return new InMemoryUserDetailsManager(user); } - public WebMVCSecurity() { - super(); + @Bean + public WebSecurityCustomizer webSecurityCustomizer() { + return (web) -> web.ignoring().antMatchers("/resources/**"); } - @Override - protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("user1").password("{noop}user1Pass").authorities("ROLE_USER"); - } - - @Override - public void configure(final WebSecurity web) throws Exception { - web.ignoring().antMatchers("/resources/**"); - } - - @Override - protected void configure(final HttpSecurity http) throws Exception { - http.authorizeRequests().anyRequest().authenticated().and().httpBasic(); + @Bean + public SecurityFilterChain filterChain(final HttpSecurity http) throws Exception { + return http.authorizeRequests().anyRequest().authenticated().and().httpBasic().and().build(); } } diff --git a/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java b/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java index 99e5c7c0cb..84098b33f8 100644 --- a/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java +++ b/xml/src/main/java/com/baeldung/xml/xml2csv/Xml2CsvExample.java @@ -40,7 +40,7 @@ public class Xml2CsvExample { protected static void convertXml2CsvXslt(String xslPath, String xmlPath, String csvPath) throws IOException, TransformerException { StreamSource styleSource = new StreamSource(new File(xslPath)); Transformer transformer = TransformerFactory.newInstance() - .newTransformer(styleSource); + .newTransformer(styleSource); Source source = new StreamSource(new File(xmlPath)); Result outputTarget = new StreamResult(new File(csvPath)); transformer.transform(source, outputTarget); @@ -68,26 +68,26 @@ public class Xml2CsvExample { if ("Bookstore".equals(currentElement)) { bookstoreInfo.setLength(0); bookstoreInfo.append(reader.getAttributeValue(null, "id")) - .append(","); + .append(","); } if ("Book".equals(currentElement)) { csvRow.append(bookstoreInfo) - .append(reader.getAttributeValue(null, "id")) - .append(",") - .append(reader.getAttributeValue(null, "category")) - .append(","); + .append(reader.getAttributeValue(null, "id")) + .append(",") + .append(reader.getAttributeValue(null, "category")) + .append(","); } if ("Author".equals(currentElement)) { csvRow.append(reader.getAttributeValue(null, "id")) - .append(","); + .append(","); } break; case XMLStreamConstants.CHARACTERS: if (!reader.isWhiteSpace()) { csvRow.append(reader.getText() - .trim()) - .append(","); + .trim()) + .append(","); } break; diff --git a/xml/src/test/java/com/baeldung/xml/xml2csv/Xml2CsvExampleUnitTest.java b/xml/src/test/java/com/baeldung/xml/xml2csv/Xml2CsvExampleUnitTest.java index 3fa44b427c..181d284b2d 100644 --- a/xml/src/test/java/com/baeldung/xml/xml2csv/Xml2CsvExampleUnitTest.java +++ b/xml/src/test/java/com/baeldung/xml/xml2csv/Xml2CsvExampleUnitTest.java @@ -91,7 +91,7 @@ public class Xml2CsvExampleUnitTest { Xml2CsvExample.convertXml2CsvXslt(STYLE_XSL, DATA_XML, TEMP_OUTPUT_CSV); File csvFile = new File(TEMP_OUTPUT_CSV); - try(BufferedReader reader = new BufferedReader(new FileReader(csvFile))) { + try (BufferedReader reader = new BufferedReader(new FileReader(csvFile))) { String line; boolean isFirstLine = true; while ((line = reader.readLine()) != null) { @@ -113,7 +113,7 @@ public class Xml2CsvExampleUnitTest { Xml2CsvExample.convertXml2CsvStax(DATA_XML, TEMP_OUTPUT_CSV); File csvFile = new File(TEMP_OUTPUT_CSV); - try(BufferedReader reader = new BufferedReader(new FileReader(csvFile))) { + try (BufferedReader reader = new BufferedReader(new FileReader(csvFile))) { String line; boolean isFirstLine = true; while ((line = reader.readLine()) != null) {