Merge branch 'master' into BAEL-7142-spring-ai

This commit is contained in:
Ekatereana 2023-11-30 21:17:32 +02:00
commit b99bff30d8
83 changed files with 1123 additions and 158 deletions

View File

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

View File

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

View File

@ -38,6 +38,16 @@
<artifactId>guava</artifactId>
<version>32.1.2-jre</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.37</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.37</version>
</dependency>
</dependencies>
<build>

View File

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

View File

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

View File

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

View File

@ -159,7 +159,7 @@
</profiles>
<properties>
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
<maven-javadoc-plugin.version>3.6.2</maven-javadoc-plugin.version>
<source.version>1.8</source.version>
<target.version>1.8</target.version>
<ascii.version>0.3.2</ascii.version>

View File

@ -33,7 +33,7 @@
<properties>
<!-- maven plugins -->
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
<maven-javadoc-plugin.version>3.6.2</maven-javadoc-plugin.version>
<source.version>1.8</source.version>
<target.version>1.8</target.version>
</properties>

View File

@ -61,7 +61,7 @@
</build>
<properties>
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
<maven-javadoc-plugin.version>3.6.2</maven-javadoc-plugin.version>
<wiremock.version>3.3.1</wiremock.version>
</properties>

View File

@ -134,7 +134,7 @@
<properties>
<!-- maven plugins -->
<maven-javadoc-plugin.version>3.5.0</maven-javadoc-plugin.version>
<maven-javadoc-plugin.version>3.6.2</maven-javadoc-plugin.version>
<hsqldb.version>2.7.1</hsqldb.version>
<!-- Mime Type Libraries -->
<tika.version>2.8.0</tika.version>

View File

@ -274,7 +274,7 @@
<mockito.version>4.6.1</mockito.version>
<!-- maven plugins -->
<javamoney.moneta.version>1.1</javamoney.moneta.version>
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
<maven-javadoc-plugin.version>3.6.2</maven-javadoc-plugin.version>
<onejar-maven-plugin.version>1.4.4</onejar-maven-plugin.version>
<maven-shade-plugin.version>3.1.1</maven-shade-plugin.version>
<maven-assembly-plugin.version>3.3.0</maven-assembly-plugin.version>

View File

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

View File

@ -177,7 +177,7 @@
<unix4j.version>0.4</unix4j.version>
<grep4j.version>1.8.7</grep4j.version>
<javamoney.moneta.version>1.1</javamoney.moneta.version>
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
<maven-javadoc-plugin.version>3.6.2</maven-javadoc-plugin.version>
<spring.core.version>4.3.20.RELEASE</spring.core.version>
</properties>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -154,7 +154,7 @@
</profiles>
<properties>
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
<maven-javadoc-plugin.version>3.6.2</maven-javadoc-plugin.version>
</properties>
</project>

View File

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

View File

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

View File

@ -2,8 +2,7 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

View File

@ -74,6 +74,17 @@
<version>${wire.mock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>4.0.0</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
@ -85,7 +96,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.5.0</version>
<version>3.1.0</version>
<executions>
<execution>
<id>xjc</id>
@ -131,6 +142,7 @@
<feign.form.spring.version>3.8.0</feign.form.spring.version>
<spring.cloud.openfeign.version>3.1.2</spring.cloud.openfeign.version>
<wire.mock.version>2.33.2</wire.mock.version>
<jakarta.xml.bind.version>4.0.0</jakarta.xml.bind.version>
</properties>
</project>

View File

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

View File

@ -164,7 +164,7 @@
<shade.plugin.version>3.2.4</shade.plugin.version>
<install.version>3.0.0-M1</install.version>
<jar.plugin.version>3.2.0</jar.plugin.version>
<javadoc.plugin.version>3.2.0</javadoc.plugin.version>
<javadoc.plugin.version>3.6.2</javadoc.plugin.version>
<resources.plugin.version>3.1.0</resources.plugin.version>
<site.plugin.version>3.9.1</site.plugin.version>
<source.plugin.version>3.2.1</source.plugin.version>

View File

@ -8,7 +8,7 @@
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<artifactId>persistence-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

View File

@ -162,7 +162,7 @@
<properties>
<datasource-proxy.version>1.6</datasource-proxy.version>
<hibernate-types.version>2.9.7</hibernate-types.version>
<hibernate.version>5.4.14.Final</hibernate.version>
<hibernate.version>5.6.15.Final</hibernate.version>
<javassist.version>3.27.0-GA</javassist.version>
<jaxb.version>2.3.1</jaxb.version>
<log4jdbc.version>2.0.0</log4jdbc.version>

View File

@ -18,6 +18,7 @@
<module>apache-bookkeeper</module>
<module>apache-cayenne</module>
<module>apache-derby</module>
<module>atomikos</module>
<module>blaze-persistence</module>
<module>core-java-persistence</module>
<module>core-java-persistence-2</module>

View File

@ -131,7 +131,7 @@
<org.springframework.data.version>1.10.6.RELEASE</org.springframework.data.version>
<org.springframework.security.version>4.2.1.RELEASE</org.springframework.security.version>
<!-- persistence -->
<hibernate.version>5.2.10.Final</hibernate.version>
<hibernate.version>5.6.15.Final</hibernate.version>
<hibernatesearch.version>5.8.2.Final</hibernatesearch.version>
<mysql-connector-java.version>8.0.7-dmr</mysql-connector-java.version>
<tomcat-dbcp.version>9.0.0.M26</tomcat-dbcp.version>

10
pom.xml
View File

@ -701,7 +701,7 @@
<module>apache-kafka</module>
<module>apache-libraries-2</module>
<module>apache-libraries</module>
<module>apache-olingo</module>
<module>apache-olingo</module><!-- apache-olingo wasn't updated to boot-3 because a workaround for jakarta namespace wasn't found JAVA-27818 -->
<module>apache-poi-2</module>
<module>apache-poi-3</module>
<module>apache-poi</module>
@ -710,7 +710,6 @@
<module>apache-velocity</module>
<module>asciidoctor</module>
<module>asm</module>
<module>atomikos</module>
<module>atomix</module>
<module>aws-modules</module>
<module>azure</module>
@ -727,7 +726,7 @@
<module>dozer</module>
<module>drools</module>
<module>dubbo</module>
<!-- <module>feign</module> --> <!-- JAVA-20337 -->
<module>feign</module>
<module>gcp-firebase</module>
<module>geotools</module>
<module>google-auto-project</module>
@ -947,7 +946,7 @@
<module>apache-kafka</module>
<module>apache-libraries-2</module>
<module>apache-libraries</module>
<module>apache-olingo</module>
<module>apache-olingo</module><!-- apache-olingo wasn't updated to boot-3 because a workaround for jakarta namespace wasn't found JAVA-27818 -->
<module>apache-poi-2</module>
<module>apache-poi-3</module>
<module>apache-poi</module>
@ -956,7 +955,6 @@
<module>apache-velocity</module>
<module>asciidoctor</module>
<module>asm</module>
<module>atomikos</module>
<module>atomix</module>
<module>aws-modules</module>
<module>azure</module>
@ -973,7 +971,7 @@
<module>dozer</module>
<module>drools</module>
<module>dubbo</module>
<!-- <module>feign</module> --> <!-- JAVA-20337 -->
<module>feign</module>
<module>gcp-firebase</module>
<module>geotools</module>
<module>google-auto-project</module>

View File

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

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.app</groupId>
<artifactId>spring-boot-groovy</artifactId>
@ -10,9 +10,10 @@
<description>Spring Boot Todo Application with Groovy</description>
<parent>
<groupId>com.baeldung.spring-boot-modules</groupId>
<artifactId>spring-boot-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-boot-3</relativePath>
</parent>
<dependencies>
@ -25,7 +26,7 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy</artifactId>
<version>${groovy.version}</version>
</dependency>
@ -39,6 +40,11 @@
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -71,8 +77,8 @@
<properties>
<start-class>com.baeldung.springwithgroovy.SpringBootGroovyApplication</start-class>
<groovy.version>3.0.13</groovy.version>
<gmavenplus-plugin.version>1.9.0</gmavenplus-plugin.version>
<groovy.version>4.0.11</groovy.version>
<gmavenplus-plugin.version>3.0.2</gmavenplus-plugin.version>
</properties>
</project>

View File

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

View File

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

View File

@ -49,6 +49,10 @@
<artifactId>commons-configuration</artifactId>
<version>${commons-configuration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
<build>
@ -61,6 +65,14 @@
<layout>JAR</layout>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>

View File

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

View File

@ -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<? extends HttpMessageConverter<?>> converterType) {
//Apply this to all Controllers
return true;
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
Class<? extends HttpMessageConverter<?>> 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<? extends HttpMessageConverter<?>> converterType) {
// Return the modified object after reading the body
return body;
}
@Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
Class<? extends HttpMessageConverter<?>> 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("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;");
}
}

View File

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

View File

@ -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<String> saveUser(@RequestBody String user) {
logger.info("save user info into database");
ResponseEntity<String> responseEntity = new ResponseEntity<>(user, HttpStatus.CREATED);
return responseEntity;
}
}

View File

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

View File

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

View File

@ -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("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll("'", "&#39;");
}
@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()));
}
}

View File

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

View File

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

View File

@ -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<String, String> requestBody = Map.of(
"name", "James Cameron",
"email", "<script>alert()</script>james@gmail.com"
);
Map<String, String> expectedResponseBody = Map.of(
"name", "James Cameron",
"email", "&lt;script&gt;alert()&lt;/script&gt;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)));
}
}

View File

@ -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<String, String> requestBody = Map.of(
"name", "James Cameron",
"email", "<script>alert()</script>james@gmail.com"
);
Map<String, String> expectedResponseBody = Map.of(
"name", "James Cameron",
"email", "&lt;script&gt;alert()&lt;/script&gt;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)));
}
}

View File

@ -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<String, String> requestBody = 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()
.is4xxClientError());
}
}

View File

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

View File

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

View File

@ -55,9 +55,9 @@
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<groupId>dev.aspectj</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>${aspectj-plugin.version}</version>
<version>${aspectj-maven-plugin.version}</version>
<configuration>
<complianceLevel>${java.version}</complianceLevel>
<aspectLibraries>
@ -80,7 +80,7 @@
<properties>
<spring-boot.version>3.1.2</spring-boot.version>
<aspectj-plugin.version>1.14.0</aspectj-plugin.version>
<aspectj-maven-plugin.version>1.13.1</aspectj-maven-plugin.version>
<log4j2.version>2.17.1</log4j2.version>
</properties>

View File

@ -10,9 +10,9 @@
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<artifactId>parent-boot-3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-2</relativePath>
<relativePath>../parent-boot-3</relativePath>
</parent>
<dependencies>
@ -35,6 +35,11 @@
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate-core.version}</version>
</dependency>
<!-- Testing -->
<dependency>
<groupId>org.springframework.boot</groupId>
@ -58,7 +63,8 @@
</build>
<properties>
<jinq.version>1.8.29</jinq.version>
<jinq.version>2.0.1</jinq.version>
<hibernate-core.version>6.4.0.Final</hibernate-core.version>
</properties>
</project>

View File

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

View File

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

View File

@ -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<Car> cars;
@Id
public String getName() {
return name;
}
@ -30,7 +31,6 @@ public class Manufacturer {
this.city = city;
}
@OneToMany(mappedBy = "model")
public List<Car> getCars() {
return cars;
}
@ -38,5 +38,4 @@ public class Manufacturer {
public void setCars(List<Car> cars) {
this.cars = cars;
}
}

View File

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

View File

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

View File

@ -276,7 +276,7 @@
<maven-jar-plugin.version>2.2</maven-jar-plugin.version>
<build-helper-maven-plugin.version>1.10</build-helper-maven-plugin.version>
<maven-compiler-plugin.version>3.6.1</maven-compiler-plugin.version>
<maven-javadoc-plugin.version>2.10.4</maven-javadoc-plugin.version>
<maven-javadoc-plugin.version>3.6.2</maven-javadoc-plugin.version>
<maven-source-plugin.version>2.2.1</maven-source-plugin.version>
<maven-gpg-plugin.version>1.5</maven-gpg-plugin.version>
</properties>

View File

@ -196,7 +196,7 @@
<maven-jar-plugin.version>2.2</maven-jar-plugin.version>
<maven-gpg-plugin.version>1.5</maven-gpg-plugin.version>
<maven-source-plugin.version>2.2.1</maven-source-plugin.version>
<maven-javadoc-plugin.version>2.10.4</maven-javadoc-plugin.version>
<maven-javadoc-plugin.version>3.6.2</maven-javadoc-plugin.version>
<build-helper-maven-plugin.version>1.10</build-helper-maven-plugin.version>
</properties>

View File

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

View File

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

View File

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