diff --git a/core-java-modules/core-java-arrays-operations-basic-2/README.md b/core-java-modules/core-java-arrays-operations-basic-2/README.md index da2f17111f..07eb82ec68 100644 --- a/core-java-modules/core-java-arrays-operations-basic-2/README.md +++ b/core-java-modules/core-java-arrays-operations-basic-2/README.md @@ -3,3 +3,4 @@ This module contains articles about Java array fundamentals. They assume no previous background knowledge on working with arrays. ### Relevant Articles: +- [Arrays mismatch() Method in Java](https://www.baeldung.com/java-arrays-mismatch) diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md index e478d87ad0..1939e5ca3f 100644 --- a/core-java-modules/core-java-collections-5/README.md +++ b/core-java-modules/core-java-collections-5/README.md @@ -7,4 +7,5 @@ - [Creating Custom Iterator in Java](https://www.baeldung.com/java-creating-custom-iterator) - [Difference Between Arrays.sort() and Collections.sort()](https://www.baeldung.com/java-arrays-collections-sort-methods) - [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration) +- [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-4) diff --git a/core-java-modules/core-java-collections-maps-7/README.md b/core-java-modules/core-java-collections-maps-7/README.md index 2724df5695..5599187cd8 100644 --- a/core-java-modules/core-java-collections-maps-7/README.md +++ b/core-java-modules/core-java-collections-maps-7/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Difference Between putIfAbsent() and computeIfAbsent() in Java’s Map](https://www.baeldung.com/java-map-putifabsent-computeifabsent) +- [How to Write Hashmap to CSV File](https://www.baeldung.com/java-write-hashmap-csv) diff --git a/core-java-modules/core-java-concurrency-basic-3/README.md b/core-java-modules/core-java-concurrency-basic-3/README.md index b9c66b279c..179a69495c 100644 --- a/core-java-modules/core-java-concurrency-basic-3/README.md +++ b/core-java-modules/core-java-concurrency-basic-3/README.md @@ -10,4 +10,5 @@ This module contains articles about basic Java concurrency. - [Returning a Value After Finishing Thread’s Job in Java](https://www.baeldung.com/java-return-value-after-thread-finish) - [CompletableFuture and ThreadPool in Java](https://www.baeldung.com/java-completablefuture-threadpool) - [CompletableFuture allOf().join() vs. CompletableFuture.join()](https://www.baeldung.com/java-completablefuture-allof-join) +- [Retry Logic with CompletableFuture](https://www.baeldung.com/java-completablefuture-retry-logic) - [[<-- Prev]](../core-java-concurrency-basic-2) diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuturelist/Application.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuturelist/Application.java new file mode 100644 index 0000000000..be5d9e8479 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuturelist/Application.java @@ -0,0 +1,100 @@ +package com.baeldung.concurrent.completablefuturelist; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.stream.Collectors; + +public class Application { + + ScheduledExecutorService asyncOperationEmulation; + + Application initialize() { + asyncOperationEmulation = Executors.newScheduledThreadPool(10); + return this; + } + + CompletableFuture asyncOperation(String operationId) { + CompletableFuture cf = new CompletableFuture<>(); + asyncOperationEmulation.submit(() -> { + // The following lines simulate an exception happening on the 567th operation + // if (operationId.endsWith("567")) { + // cf.completeExceptionally(new Exception("Error on operation " + operationId)); + // return; + // } + try { + Thread.sleep(100); + cf.complete(operationId); + } catch (InterruptedException e) { + System.err.println("Thread interrupted error"); + cf.completeExceptionally(e); + } + }); + return cf; + } + + void startNaive() { + List> futures = new ArrayList<>(); + for (int i = 1; i <= 1000; i++) { + String operationId = "Naive-Operation-" + i; + futures.add(asyncOperation(operationId)); + } + + CompletableFuture> aggregate = CompletableFuture.completedFuture(new ArrayList<>()); + for (CompletableFuture future : futures) { + aggregate = aggregate.thenCompose(list -> { + try { + list.add(future.get()); + return CompletableFuture.completedFuture(list); + } catch (Exception e) { + final CompletableFuture> excFuture = new CompletableFuture<>(); + excFuture.completeExceptionally(e); + return excFuture; + } + }); + } + + try { + final List results = aggregate.join(); + System.out.println("Printing first 10 results"); + for (int i = 0; i < 10; i++) { + System.out.println("Finished " + results.get(i)); + } + } finally { + close(); + } + } + + void start() { + List> futures = new ArrayList<>(); + for (int i = 1; i <= 1000; i++) { + String operationId = "Operation-" + i; + futures.add(asyncOperation(operationId)); + } + CompletableFuture[] futuresArray = futures.toArray(new CompletableFuture[0]); + CompletableFuture> listFuture = CompletableFuture.allOf(futuresArray).thenApply(v -> futures.stream().map(CompletableFuture::join).collect(Collectors.toList())); + try { + final List results = listFuture.join(); + System.out.println("Printing first 10 results"); + for (int i = 0; i < 10; i++) { + System.out.println("Finished " + results.get(i)); + } + } finally { + close(); + } + } + + void close() { + asyncOperationEmulation.shutdownNow(); + } + + public static void main(String[] args) { + new Application().initialize() + // Switch between .startNaive() and .start() to test both implementations + // .startNaive(); + .start(); + } + +} diff --git a/core-java-modules/core-java-concurrency-simple/README.md b/core-java-modules/core-java-concurrency-simple/README.md index 5cbfc67862..422d33e2c3 100644 --- a/core-java-modules/core-java-concurrency-simple/README.md +++ b/core-java-modules/core-java-concurrency-simple/README.md @@ -12,6 +12,7 @@ This module contains articles about Java Concurrency that are also part of an Eb - [Guide to the Volatile Keyword in Java](https://www.baeldung.com/java-volatile) - [A Guide to the Java ExecutorService](https://www.baeldung.com/java-executor-service-tutorial) - [Guide To CompletableFuture](https://www.baeldung.com/java-completablefuture) +- [How To Manage Timeout for CompletableFuture](https://www.baeldung.com/java-completablefuture-timeout) ### NOTE: diff --git a/core-java-modules/core-java-io-5/pom.xml b/core-java-modules/core-java-io-5/pom.xml index 11116b071c..5c987a82e1 100644 --- a/core-java-modules/core-java-io-5/pom.xml +++ b/core-java-modules/core-java-io-5/pom.xml @@ -35,6 +35,21 @@ simplemagic ${simplemagic.version} + + commons-io + commons-io + ${commons-io.version} + + + org.openjdk.jmh + jmh-core + ${jmh.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + @@ -62,5 +77,6 @@ 0.1.5 6.2.1 1.17 + 1.37 \ No newline at end of file diff --git a/core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipBenchmark.java b/core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipBenchmark.java new file mode 100644 index 0000000000..30ec1522a2 --- /dev/null +++ b/core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipBenchmark.java @@ -0,0 +1,112 @@ +package com.baeldung.zip; + +import java.io.*; +import java.util.concurrent.TimeUnit; +import java.util.*; +import java.util.zip.*; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 1, time = 2, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Fork(value = 1) +public class ZipBenchmark { + + public static final int NUM_OF_FILES = 10; + public static final int DATA_SIZE = 204800; + + @State(Scope.Thread) + public static class SourceState { + + public File compressedFile; + + @Setup(Level.Trial) + public void setup() throws IOException { + ZipSampleFileStore sampleFileStore = new ZipSampleFileStore(NUM_OF_FILES, DATA_SIZE); + compressedFile = sampleFileStore.getFile(); + } + + @TearDown(Level.Trial) + public void cleanup() { + if (compressedFile.exists()) { + compressedFile.delete(); + } + } + } + + @Benchmark + public static void readAllEntriesByZipFile(SourceState sourceState, Blackhole blackhole) throws IOException { + + try (ZipFile zipFile = new ZipFile(sourceState.compressedFile)) { + Enumeration zipEntries = zipFile.entries(); + while (zipEntries.hasMoreElements()) { + ZipEntry zipEntry = zipEntries.nextElement(); + try (InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(zipEntry))) { + blackhole.consume(ZipSampleFileStore.getString(inputStream)); + } + } + } + } + + @Benchmark + public static void readAllEntriesByZipInputStream(SourceState sourceState, Blackhole blackhole) throws IOException { + + try ( + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceState.compressedFile)); + ZipInputStream zipInputStream = new ZipInputStream(bis) + ) { + ZipEntry entry; + while ((entry = zipInputStream.getNextEntry()) != null) { + blackhole.consume(ZipSampleFileStore.getString(zipInputStream)); + } + } + } + + @Benchmark + public static void readLastEntryByZipFile(SourceState sourceState, Blackhole blackhole) throws IOException { + + try (ZipFile zipFile = new ZipFile(sourceState.compressedFile)) { + ZipEntry zipEntry = zipFile.getEntry(getLastEntryName()); + try (InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(zipEntry))) { + blackhole.consume(ZipSampleFileStore.getString(inputStream)); + } + } + } + + @Benchmark + public static void readLastEntryByZipInputStream(SourceState sourceState, Blackhole blackhole) throws IOException { + + try ( + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceState.compressedFile)); + ZipInputStream zipInputStream = new ZipInputStream(bis) + ) { + ZipEntry entry; + while ((entry = zipInputStream.getNextEntry()) != null) { + if (Objects.equals(entry.getName(), getLastEntryName())){ + blackhole.consume(ZipSampleFileStore.getString(zipInputStream)); + } + } + } + } + + private static String getLastEntryName() { + return String.format(ZipSampleFileStore.ENTRY_NAME_PATTERN, NUM_OF_FILES); + } + + public static void main(String[] args) throws Exception { + Options options = new OptionsBuilder() + .include(ZipBenchmark.class.getSimpleName()).threads(1) + .shouldFailOnError(true) + .shouldDoGC(true) + .jvmArgs("-server").build(); + new Runner(options).run(); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipSampleFileStore.java b/core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipSampleFileStore.java new file mode 100644 index 0000000000..389f082ff1 --- /dev/null +++ b/core-java-modules/core-java-io-5/src/main/java/com/baeldung/zip/ZipSampleFileStore.java @@ -0,0 +1,70 @@ +package com.baeldung.zip; + +import java.io.*; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.apache.commons.io.IOUtils; + +public class ZipSampleFileStore { + + public static final String ENTRY_NAME_PATTERN = "str-data-%s.txt"; + private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8; + + private final File file; + private final List dataList; + + public ZipSampleFileStore(int numOfFiles, int fileSize) throws IOException { + + dataList = new ArrayList<>(numOfFiles); + file = File.createTempFile("zip-sample", ""); + + try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(file))) { + + for (int idx=0; idx<=numOfFiles; idx++) { + + byte[] data = createRandomStringInByte(fileSize); + dataList.add(new String(data, DEFAULT_ENCODING)); + + ZipEntry entry = new ZipEntry(String.format(ENTRY_NAME_PATTERN, idx)); + zos.putNextEntry(entry); + zos.write(data); + zos.closeEntry(); + } + } + } + + public static byte[] createRandomStringInByte(int size) { + Random random = new Random(); + byte[] data = new byte[size]; + for (int n = 0; n < data.length; n++) { + char randomChar; + int choice = random.nextInt(2); // 0 for uppercase, 1 for lowercase + if (choice == 0) { + randomChar = (char) ('A' + random.nextInt(26)); // 'A' to 'Z' + } else { + randomChar = (char) ('a' + random.nextInt(26)); // 'a' to 'z' + } + data[n] = (byte) randomChar; + } + return data; + } + + public File getFile() { + return file; + } + + public List getDataList() { + return dataList; + } + + public static String getString(InputStream inputStream) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + IOUtils.copy(inputStream, byteArrayOutputStream); + return byteArrayOutputStream.toString(DEFAULT_ENCODING); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-io-5/src/test/java/com/baeldung/zip/ZipUnitTest.java b/core-java-modules/core-java-io-5/src/test/java/com/baeldung/zip/ZipUnitTest.java new file mode 100644 index 0000000000..1d4d76dc41 --- /dev/null +++ b/core-java-modules/core-java-io-5/src/test/java/com/baeldung/zip/ZipUnitTest.java @@ -0,0 +1,83 @@ +package com.baeldung.zip; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.*; +import java.util.*; +import java.util.zip.*; + +import org.junit.*; + +public class ZipUnitTest { + + private static File compressedFile; + private static List dataList = new ArrayList<>(); + + @BeforeClass + public static void prepareData() throws IOException { + ZipSampleFileStore sampleFileStore = new ZipSampleFileStore(ZipBenchmark.NUM_OF_FILES, ZipBenchmark.DATA_SIZE); + compressedFile = sampleFileStore.getFile(); + dataList = sampleFileStore.getDataList(); + } + + @Test + public void whenCreateZipFile_thenCompressedSizeShouldBeLessThanOriginal() throws IOException { + byte[] data = ZipSampleFileStore.createRandomStringInByte(10240); + File file = File.createTempFile("zip-temp", ""); + + try ( + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); + ZipOutputStream zos = new ZipOutputStream(bos) + ) { + ZipEntry zipEntry = new ZipEntry("zip-entry.txt"); + zos.putNextEntry(zipEntry); + zos.write(data); + zos.closeEntry(); + + assertThat(file.length()).isLessThan(data.length); + } + finally { + file.delete(); + } + } + + @Test + public void whenReadAllEntriesViaZipFile_thenDataIsEqualtoTheSource() throws IOException { + + try (ZipFile zipFile = new ZipFile(compressedFile)) { + Enumeration entries = zipFile.entries(); + List entryList = Collections.list(entries); + + for (int idx=0; idxspring-jpa spring-jpa-2 spring-jdbc + spring-jdbc-2 spring-jooq spring-mybatis spring-persistence-simple diff --git a/persistence-modules/spring-jdbc-2/pom.xml b/persistence-modules/spring-jdbc-2/pom.xml new file mode 100644 index 0000000000..ce79c1c615 --- /dev/null +++ b/persistence-modules/spring-jdbc-2/pom.xml @@ -0,0 +1,93 @@ + + + 4.0.0 + + org.example + spring-jdbc-2 + 1.0-SNAPSHOT + spring-jdbc-2 + Demo project for Spring Jdbc + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.h2database + h2 + runtime + + + org.springframework.boot + spring-boot-starter-test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + false + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + false + + + + + + 3.2.0-SNAPSHOT + 5.10.0 + UTF-8 + + + \ No newline at end of file diff --git a/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/JdbcClientDemoApplication.java b/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/JdbcClientDemoApplication.java new file mode 100644 index 0000000000..d10124fdef --- /dev/null +++ b/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/JdbcClientDemoApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.jdbcclient; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackages = "com.baledung.jdbcclient") +public class JdbcClientDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(JdbcClientDemoApplication.class, args); + } +} diff --git a/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/dao/StudentDao.java b/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/dao/StudentDao.java new file mode 100644 index 0000000000..ba5bfcee11 --- /dev/null +++ b/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/dao/StudentDao.java @@ -0,0 +1,95 @@ +package com.baeldung.jdbcclient.dao; + +import com.baeldung.jdbcclient.model.Student; +import com.baeldung.jdbcclient.model.StudentResultExtractor; +import com.baeldung.jdbcclient.model.StudentRowMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.RowCountCallbackHandler; +import org.springframework.jdbc.core.simple.JdbcClient; +import org.springframework.stereotype.Repository; + +import java.sql.Types; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@Repository +public class StudentDao { + + private static final Logger logger = LoggerFactory.getLogger(StudentDao.class); + @Autowired + private JdbcClient jdbcClient; + + public Integer insertWithSetParamWithNamedParamAndSqlType(Student student) { + String sql = "INSERT INTO student (student_name, age, grade, gender, state)" + + "VALUES (:name, :age, :grade, :gender, :state)"; + Integer noOfrowsAffected = this.jdbcClient.sql(sql) + .param("name", student.getStudentName(), Types.VARCHAR) + .param("age", student.getAge(), Types.INTEGER) + .param("grade", student.getGrade(), Types.INTEGER) + .param("gender", student.getStudentGender(), Types.VARCHAR) + .param("state", student.getState(), Types.VARCHAR) + .update(); + logger.info("No. of rows affected: " + noOfrowsAffected); + return noOfrowsAffected; + } + + public List getStudentsOfGradeStateAndGenderWithPositionalParams(int grade, String state, String gender) { + String sql = "select student_id, student_name, age, grade, gender, state from student" + + " where grade = ? and state = ? and gender = ?"; + return jdbcClient.sql(sql) + .param(grade) + .param(state) + .param(gender) + .query(new StudentRowMapper()).list(); + } + + public List getStudentsOfGradeStateAndGenderWithParamIndex(int grade, String state, String gender) { + String sql = "select student_id, student_name, age, grade, gender, state from student" + + " where grade = ? and state = ? and gender = ?"; + return jdbcClient.sql(sql) + .param(1,grade) + .param(2, state) + .param(3, gender) + .query(new StudentResultExtractor()); + } + + public Student getStudentsOfGradeStateAndGenderWithParamsInVarargs(int grade, String state, String gender) { + String sql = "select student_id, student_name, age, grade, gender, state from student" + + " where grade = ? and state = ? and gender = ? limit 1"; + return jdbcClient.sql(sql) + .params(grade, state, gender) + .query(new StudentRowMapper()).single(); + } + + public Optional getStudentsOfGradeStateAndGenderWithParamsInList(List params) { + String sql = "select student_id, student_name, age, grade, gender, state from student" + + " where grade = ? and state = ? and gender = ? limit 1"; + return jdbcClient.sql(sql) + .params(params) + .query(new StudentRowMapper()).optional(); + } + + + public int getCountOfStudentsOfGradeStateAndGenderWithNamedParam(int grade, String state, String gender) { + String sql = "select student_id, student_name, age, grade, gender, state from student" + + " where grade = :grade and state = :state and gender = :gender"; + RowCountCallbackHandler countCallbackHandler = new RowCountCallbackHandler(); + jdbcClient.sql(sql) + .param("grade", grade) + .param("state", state) + .param("gender", gender) + .query(countCallbackHandler); + return countCallbackHandler.getRowCount(); + } + + public List getStudentsOfGradeStateAndGenderWithParamMap(Map paramMap) { + String sql = "select student_id, student_name, age, grade, gender, state from student" + + " where grade = :grade and state = :state and gender = :gender"; + return jdbcClient.sql(sql) + .params(paramMap) + .query(new StudentRowMapper()).list(); + } +} diff --git a/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/model/Student.java b/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/model/Student.java new file mode 100644 index 0000000000..3de8a6e1f9 --- /dev/null +++ b/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/model/Student.java @@ -0,0 +1,60 @@ +package com.baeldung.jdbcclient.model; + +public class Student { + private Integer studentId; + private String studentName; + private String studentGender; + private Integer age; + private Integer grade; + + public Integer getStudentId() { + return studentId; + } + + public void setStudentId(Integer studentId) { + this.studentId = studentId; + } + + public String getStudentName() { + return studentName; + } + + public void setStudentName(String studentName) { + this.studentName = studentName; + } + + public String getStudentGender() { + return studentGender; + } + + public void setStudentGender(String studentGender) { + this.studentGender = studentGender; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Integer getGrade() { + return grade; + } + + public void setGrade(Integer grade) { + this.grade = grade; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + private String state; + +} diff --git a/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/model/StudentResultExtractor.java b/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/model/StudentResultExtractor.java new file mode 100644 index 0000000000..29cb60cee9 --- /dev/null +++ b/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/model/StudentResultExtractor.java @@ -0,0 +1,26 @@ +package com.baeldung.jdbcclient.model; + +import org.springframework.jdbc.core.ResultSetExtractor; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class StudentResultExtractor implements ResultSetExtractor> { + @Override + public List extractData(ResultSet rs) throws SQLException { + List students = new ArrayList(); + while(rs.next()) { + Student student = new Student(); + student.setStudentId(rs.getInt("student_id")); + student.setStudentName(rs.getString("student_name")); + student.setAge(rs.getInt("age")); + student.setStudentGender(rs.getString("gender")); + student.setGrade(rs.getInt("grade")); + student.setState(rs.getString("state")); + students.add(student); + } + return students; + } +} diff --git a/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/model/StudentRowMapper.java b/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/model/StudentRowMapper.java new file mode 100644 index 0000000000..c387a6c485 --- /dev/null +++ b/persistence-modules/spring-jdbc-2/src/main/java/com/baeldung/jdbcclient/model/StudentRowMapper.java @@ -0,0 +1,20 @@ +package com.baeldung.jdbcclient.model; + +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class StudentRowMapper implements RowMapper { + @Override + public Student mapRow(ResultSet rs, int rowNum) throws SQLException { + Student student = new Student(); + student.setStudentId(rs.getInt("student_id")); + student.setStudentName(rs.getString("student_name")); + student.setAge(rs.getInt("age")); + student.setStudentGender(rs.getString("gender")); + student.setGrade(rs.getInt("grade")); + student.setState(rs.getString("state")); + return student; + } +} diff --git a/persistence-modules/spring-jdbc-2/src/main/resources/jdbcclient/application.properties b/persistence-modules/spring-jdbc-2/src/main/resources/jdbcclient/application.properties new file mode 100644 index 0000000000..04c963ebf4 --- /dev/null +++ b/persistence-modules/spring-jdbc-2/src/main/resources/jdbcclient/application.properties @@ -0,0 +1,5 @@ +# DataSource Configuration +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=user +spring.datasource.password= # Leave this empty \ No newline at end of file diff --git a/persistence-modules/spring-jdbc-2/src/main/resources/jdbcclient/drop_student.sql b/persistence-modules/spring-jdbc-2/src/main/resources/jdbcclient/drop_student.sql new file mode 100644 index 0000000000..954545a862 --- /dev/null +++ b/persistence-modules/spring-jdbc-2/src/main/resources/jdbcclient/drop_student.sql @@ -0,0 +1 @@ +DROP TABLE student; \ No newline at end of file diff --git a/persistence-modules/spring-jdbc-2/src/main/resources/jdbcclient/student.sql b/persistence-modules/spring-jdbc-2/src/main/resources/jdbcclient/student.sql new file mode 100644 index 0000000000..0e137f5445 --- /dev/null +++ b/persistence-modules/spring-jdbc-2/src/main/resources/jdbcclient/student.sql @@ -0,0 +1,98 @@ + +CREATE TABLE student ( + student_id INT AUTO_INCREMENT PRIMARY KEY, + student_name VARCHAR(255) NOT NULL, + age INT, + grade INT NOT NULL, + gender VARCHAR(10) NOT NULL, + state VARCHAR(100) NOT NULL +); +-- Student 1 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('John Smith', 18, 3, 'Male', 'California'); + +-- Student 2 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Emily Johnson', 17, 2, 'Female', 'New York'); + +-- Student 3 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Michael Davis', 4, 1, 'Male', 'Texas'); + +-- Student 4 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Sophia Martinez', 2, 1, 'Female', 'Florida'); + +-- Student 5 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('William Brown', 5, 5, 'Male', 'California'); + +-- Student 6 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Olivia Garcia', 4, 2, 'Female', 'Texas'); + +-- Student 7 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Ethan Rodriguez', 3, 1, 'Male', 'New York'); + +-- Student 8 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Ava Hernandez', 2, 1, 'Female', 'Florida'); + +-- Student 9 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('James Wilson', 5, 4, 'Male', 'Texas'); + +-- Student 10 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Emma Miller', 3, 1, 'Female', 'California'); + +-- Student 11 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Benjamin Brown', 4, 1, 'Male', 'New York'); + +-- Student 12 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Mia Smith', 2, 1, 'Female', 'Florida'); + +-- Student 13 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Daniel Johnson', 5, 4, 'Male', 'California'); + +-- Student 14 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Ava Davis', 4, 2, 'Female', 'Texas'); + +-- Student 15 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Matthew Martinez', 3, 1, 'Male', 'New York'); + +-- Student 16 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Sophia Taylor', 2, 1, 'Female', 'Florida'); + +-- Student 17 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Alexander White', 5, 4, 'Male', 'California'); + +-- Student 18 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Olivia Johnson', 4, 2, 'Female', 'Texas'); + +-- Student 19 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Christopher Lee', 3, 1, 'Male', 'New York'); + +-- Student 20 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Emma Wilson', 2, 1, 'Female', 'Florida'); + +-- Student 21 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Elijah Smith', 5, 3, 'Male', 'Texas'); + +-- Student 22 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Isabella Davis', 4, 2, 'Female', 'California'); + +-- Student 23 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Liam Johnson', 3, 1, 'Male', 'New York'); + +-- Student 24 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Olivia Garcia', 2, 1, 'Female', 'Florida'); + +-- Student 25 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Noah Rodriguez', 5, 3, 'Male', 'Texas'); + +-- Student 26 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Sophia Hernandez', 4, 2, 'Female', 'California'); + +-- Student 27 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Mason Smith', 3, 1, 'Male', 'New York'); + +-- Student 28 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Ava Taylor', 2, 1, 'Female', 'Florida'); + +-- Student 29 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('William Brown', 5, 5, 'Male', 'Texas'); + +-- Student 30 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Olivia Martinez', 4, 4, 'Female', 'California'); diff --git a/persistence-modules/spring-jdbc-2/src/test/java/com/baeldung/jdbcclient/JdbcClientUnitTest.java b/persistence-modules/spring-jdbc-2/src/test/java/com/baeldung/jdbcclient/JdbcClientUnitTest.java new file mode 100644 index 0000000000..be30efcb9c --- /dev/null +++ b/persistence-modules/spring-jdbc-2/src/test/java/com/baeldung/jdbcclient/JdbcClientUnitTest.java @@ -0,0 +1,104 @@ +package com.baeldung.jdbcclient; + +import com.baeldung.jdbcclient.dao.StudentDao; +import com.baeldung.jdbcclient.model.Student; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.jdbc.Sql; + +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +@Sql(value = "/jdbcclient/student.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +@Sql(value = "/jdbcclient/drop_student.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) +@SpringBootTest(classes = JdbcClientDemoApplication.class) +@TestPropertySource(locations = {"classpath:jdbcclient/application.properties"}) + +public class JdbcClientUnitTest { + private static final Logger logger = LoggerFactory.getLogger(JdbcClientUnitTest.class); + + @Autowired + private StudentDao studentDao; + + @Test + void givenJdbcClient_whenInsertWithNamedParamAndSqlType_thenSuccess() { + logger.info("testing invoked successfully"); + Student student = getSampleStudent("Johny Dep", 8, 4, "Male", "New York"); + assertEquals(1, studentDao.insertWithSetParamWithNamedParamAndSqlType(student)); + } + + @Test + void givenJdbcClient_whenQueryWithPositionalParams_thenSuccess() { + logger.info("testing invoked successfully"); + List students = studentDao.getStudentsOfGradeStateAndGenderWithPositionalParams( + 1, "New York", "Male"); + logger.info("number of students fetched " + students.size()); + assertEquals(6, students.size()); + } + + @Test + void givenJdbcClient_whenQueryWithParamsInVarargs_thenSuccess() { + logger.info("testing invoked successfully"); + Student student = studentDao.getStudentsOfGradeStateAndGenderWithParamsInVarargs( + 1, "New York", "Male"); + assertNotNull(student); + } + + @Test + void givenJdbcClient_whenQueryWithParamsInList_thenSuccess() { + logger.info("testing invoked successfully"); + List params = List.of(1, "New York", "Male"); + Optional optional = studentDao.getStudentsOfGradeStateAndGenderWithParamsInList(params); + if(optional.isPresent()) { + assertNotNull(optional.get()); + } else { + assertThrows(NoSuchElementException.class, () -> optional.get()); + } + } + + @Test + void givenJdbcClient_whenQueryWithParamsIndex_thenSuccess() { + logger.info("testing invoked successfully"); + List students = studentDao.getStudentsOfGradeStateAndGenderWithParamIndex( + 1, "New York", "Male"); + assertEquals(6, students.size()); + } + @Test + void givenJdbcClient_whenQueryWithNamedParam_thenSuccess() { + logger.info("testing invoked successfully"); + Integer count = studentDao.getCountOfStudentsOfGradeStateAndGenderWithNamedParam( + 1, "New York", "Male"); + logger.info("number of students fetched " + count); + assertEquals(6, count); + } + @Test + void givenJdbcClient_whenQueryWithParamMap_thenSuccess() { + logger.info("testing invoked successfully"); + Map paramMap = Map.of( + "grade", 1, + "gender", "Male", + "state", "New York" + ); + List students = studentDao.getStudentsOfGradeStateAndGenderWithParamMap(paramMap); + logger.info("number of students fetched " + students.size()); + assertEquals(6, students.size()); + } + + private Student getSampleStudent(String name, int age, int grade, String gender, String state) { + Student student = new Student(); + student.setStudentName(name); + student.setStudentGender(gender); + student.setAge(age); + student.setGrade(grade); + student.setState(state); + return student; + } +} diff --git a/persistence-modules/spring-jdbc-2/src/test/resources/logback-test.xml b/persistence-modules/spring-jdbc-2/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8d4771e308 --- /dev/null +++ b/persistence-modules/spring-jdbc-2/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 07b9d6d842..7bde142fbc 100644 --- a/pom.xml +++ b/pom.xml @@ -349,7 +349,6 @@ - @@ -362,7 +361,7 @@ muleesb web-modules/java-lite persistence-modules/deltaspike - persistence-modules/hibernate-ogm + persistence-modules/hibernate-ogm persistence-modules/spring-data-cassandra-reactive java-nashorn jeromq @@ -523,7 +522,6 @@ - @@ -534,7 +532,7 @@ muleesb web-modules/java-lite persistence-modules/deltaspike - persistence-modules/hibernate-ogm + persistence-modules/hibernate-ogm persistence-modules/spring-data-cassandra-reactive java-nashorn jeromq diff --git a/spring-boot-modules/spring-boot-3-2/README.md b/spring-boot-modules/spring-boot-3-2/README.md new file mode 100644 index 0000000000..c176de2310 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-2/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Spring Boot 3.1’s ConnectionDetails Abstraction](https://www.baeldung.com/spring-boot-3-1-connectiondetails-abstraction) diff --git a/spring-boot-modules/spring-boot-3/README.md b/spring-boot-modules/spring-boot-3/README.md index 8791aaae1f..ded5db30e4 100644 --- a/spring-boot-modules/spring-boot-3/README.md +++ b/spring-boot-modules/spring-boot-3/README.md @@ -8,3 +8,4 @@ - [HTTP Interface in Spring 6](https://www.baeldung.com/spring-6-http-interface) - [Working with Virtual Threads in Spring 6](https://www.baeldung.com/spring-6-virtual-threads) - [Docker Compose Support in Spring Boot 3](https://www.baeldung.com/ops/docker-compose-support-spring-boot) +- [A Guide to RestClient in Spring Boot](https://www.baeldung.com/spring-boot-restclient) diff --git a/spring-boot-modules/spring-boot-data-2/README.md b/spring-boot-modules/spring-boot-data-2/README.md index 9ff2b2caf8..8e6619dce4 100644 --- a/spring-boot-modules/spring-boot-data-2/README.md +++ b/spring-boot-modules/spring-boot-data-2/README.md @@ -1,7 +1,6 @@ ### Relevant Articles: - [HttpMessageNotWritableException: No Converter for [class …] With Preset Content-Type](https://www.baeldung.com/spring-no-converter-with-preset) -- [Spring Boot: Customize the Jackson ObjectMapper](https://www.baeldung.com/spring-boot-customize-jackson-objectmapper) - [“HttpMessageNotWritableException: No converter found for return value of type”](https://www.baeldung.com/spring-no-converter-found) - [Creating a Read-Only Repository with Spring Data](https://www.baeldung.com/spring-data-read-only-repository) - [Using JaVers for Data Model Auditing in Spring Data](https://www.baeldung.com/spring-data-javers-audit) diff --git a/spring-boot-modules/spring-boot-data/README.md b/spring-boot-modules/spring-boot-data/README.md index c56c87014d..aa745b77a2 100644 --- a/spring-boot-modules/spring-boot-data/README.md +++ b/spring-boot-modules/spring-boot-data/README.md @@ -11,4 +11,5 @@ This module contains articles about Spring Boot with Spring Data - [Spring Custom Property Editor](https://www.baeldung.com/spring-mvc-custom-property-editor) - [Using @JsonComponent in Spring Boot](https://www.baeldung.com/spring-boot-jsoncomponent) - [Guide To Running Logic on Startup in Spring](https://www.baeldung.com/running-setup-logic-on-startup-in-spring) +- [Spring Boot: Customize the Jackson ObjectMapper](https://www.baeldung.com/spring-boot-customize-jackson-objectmapper) diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/app/Application.java b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/app/Application.java similarity index 100% rename from spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/app/Application.java rename to spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/app/Application.java diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeConstants.java b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeConstants.java similarity index 100% rename from spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeConstants.java rename to spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeConstants.java index d1875d03d9..ecb07e44b1 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeConstants.java +++ b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeConstants.java @@ -1,10 +1,10 @@ package com.baeldung.boot.jackson.config; -import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; - import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; + public class CoffeeConstants { public static final String DATETIME_FORMAT = "dd-MM-yyyy HH:mm"; diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeCustomizerConfig.java b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeCustomizerConfig.java similarity index 99% rename from spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeCustomizerConfig.java rename to spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeCustomizerConfig.java index edb2b478fc..0aa2d3eb96 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeCustomizerConfig.java +++ b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeCustomizerConfig.java @@ -1,11 +1,12 @@ package com.baeldung.boot.jackson.config; -import com.fasterxml.jackson.annotation.JsonInclude; +import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; + import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; +import com.fasterxml.jackson.annotation.JsonInclude; @Configuration public class CoffeeCustomizerConfig { diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeHttpConverterConfiguration.java b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeHttpConverterConfiguration.java similarity index 99% rename from spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeHttpConverterConfiguration.java rename to spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeHttpConverterConfiguration.java index eff2b5c252..be8e3bb34d 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeHttpConverterConfiguration.java +++ b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeHttpConverterConfiguration.java @@ -1,12 +1,13 @@ package com.baeldung.boot.jackson.config; -import com.fasterxml.jackson.annotation.JsonInclude; +import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; +import com.fasterxml.jackson.annotation.JsonInclude; @Configuration public class CoffeeHttpConverterConfiguration { diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeJacksonBuilderConfig.java b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeJacksonBuilderConfig.java similarity index 99% rename from spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeJacksonBuilderConfig.java rename to spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeJacksonBuilderConfig.java index 8057fff3db..19501f872c 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeJacksonBuilderConfig.java +++ b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeJacksonBuilderConfig.java @@ -1,12 +1,13 @@ package com.baeldung.boot.jackson.config; -import com.fasterxml.jackson.annotation.JsonInclude; +import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; -import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; +import com.fasterxml.jackson.annotation.JsonInclude; @Configuration public class CoffeeJacksonBuilderConfig { diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeObjectMapperConfig.java b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeObjectMapperConfig.java similarity index 99% rename from spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeObjectMapperConfig.java rename to spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeObjectMapperConfig.java index f1ce6458ae..cadf17b6b8 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeObjectMapperConfig.java +++ b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeObjectMapperConfig.java @@ -1,13 +1,14 @@ package com.baeldung.boot.jackson.config; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; -import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; @Configuration public class CoffeeObjectMapperConfig { diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeRegisterModuleConfig.java b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeRegisterModuleConfig.java similarity index 88% rename from spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeRegisterModuleConfig.java rename to spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeRegisterModuleConfig.java index fc157f8156..55a928dabc 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/config/CoffeeRegisterModuleConfig.java +++ b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/config/CoffeeRegisterModuleConfig.java @@ -1,19 +1,19 @@ package com.baeldung.boot.jackson.config; -import com.fasterxml.jackson.databind.Module; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; -import static com.baeldung.boot.jackson.config.CoffeeConstants.LOCAL_DATETIME_SERIALIZER; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; @Configuration @PropertySource("classpath:coffee.properties") public class CoffeeRegisterModuleConfig { @Bean - public Module javaTimeModule() { + public JavaTimeModule javaTimeModule() { JavaTimeModule module = new JavaTimeModule(); module.addSerializer(LOCAL_DATETIME_SERIALIZER); return module; diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/controller/CoffeeController.java b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/controller/CoffeeController.java similarity index 99% rename from spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/controller/CoffeeController.java rename to spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/controller/CoffeeController.java index 23749b18a2..36489a645a 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/controller/CoffeeController.java +++ b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/controller/CoffeeController.java @@ -1,11 +1,12 @@ package com.baeldung.boot.jackson.controller; -import com.baeldung.boot.jackson.model.Coffee; +import static com.baeldung.boot.jackson.config.CoffeeConstants.FIXED_DATE; + import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import static com.baeldung.boot.jackson.config.CoffeeConstants.FIXED_DATE; +import com.baeldung.boot.jackson.model.Coffee; @RestController public class CoffeeController { diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/model/Coffee.java b/spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/model/Coffee.java similarity index 100% rename from spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/jackson/model/Coffee.java rename to spring-boot-modules/spring-boot-data/src/main/java/com/baeldung/boot/jackson/model/Coffee.java diff --git a/spring-boot-modules/spring-boot-data-2/src/main/resources/coffee.properties b/spring-boot-modules/spring-boot-data/src/main/resources/coffee.properties similarity index 100% rename from spring-boot-modules/spring-boot-data-2/src/main/resources/coffee.properties rename to spring-boot-modules/spring-boot-data/src/main/resources/coffee.properties diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/AbstractCoffeeIntegrationTest.java b/spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/AbstractCoffeeIntegrationTest.java similarity index 99% rename from spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/AbstractCoffeeIntegrationTest.java rename to spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/AbstractCoffeeIntegrationTest.java index f1bc35a8ce..961ab8979c 100644 --- a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/AbstractCoffeeIntegrationTest.java +++ b/spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/AbstractCoffeeIntegrationTest.java @@ -1,15 +1,16 @@ package com.baeldung.boot.jackson.app; -import com.baeldung.boot.jackson.config.CoffeeConstants; +import static com.baeldung.boot.jackson.config.CoffeeConstants.FIXED_DATE; +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.format.DateTimeFormatter; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import java.time.format.DateTimeFormatter; - -import static com.baeldung.boot.jackson.config.CoffeeConstants.FIXED_DATE; -import static org.assertj.core.api.Assertions.assertThat; +import com.baeldung.boot.jackson.config.CoffeeConstants; @SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public abstract class AbstractCoffeeIntegrationTest { diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeCustomizerIntegrationTest.java b/spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeCustomizerIntegrationTest.java similarity index 99% rename from spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeCustomizerIntegrationTest.java rename to spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeCustomizerIntegrationTest.java index d690de1b9c..ed5baf239c 100644 --- a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeCustomizerIntegrationTest.java +++ b/spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeCustomizerIntegrationTest.java @@ -1,8 +1,9 @@ package com.baeldung.boot.jackson.app; -import com.baeldung.boot.jackson.config.CoffeeCustomizerConfig; import org.springframework.context.annotation.Import; +import com.baeldung.boot.jackson.config.CoffeeCustomizerConfig; + @Import(CoffeeCustomizerConfig.class) public class CoffeeCustomizerIntegrationTest extends AbstractCoffeeIntegrationTest { } diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeHttpConverterIntegrationTest.java b/spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeHttpConverterIntegrationTest.java similarity index 99% rename from spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeHttpConverterIntegrationTest.java rename to spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeHttpConverterIntegrationTest.java index 62b1d42152..0c77948d8e 100644 --- a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeHttpConverterIntegrationTest.java +++ b/spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeHttpConverterIntegrationTest.java @@ -1,8 +1,9 @@ package com.baeldung.boot.jackson.app; -import com.baeldung.boot.jackson.config.CoffeeHttpConverterConfiguration; import org.springframework.context.annotation.Import; +import com.baeldung.boot.jackson.config.CoffeeHttpConverterConfiguration; + @Import(CoffeeHttpConverterConfiguration.class) public class CoffeeHttpConverterIntegrationTest extends AbstractCoffeeIntegrationTest { } diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeJacksonBuilderIntegrationTest.java b/spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeJacksonBuilderIntegrationTest.java similarity index 99% rename from spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeJacksonBuilderIntegrationTest.java rename to spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeJacksonBuilderIntegrationTest.java index 52a55394c0..da9251de99 100644 --- a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeJacksonBuilderIntegrationTest.java +++ b/spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeJacksonBuilderIntegrationTest.java @@ -1,8 +1,9 @@ package com.baeldung.boot.jackson.app; -import com.baeldung.boot.jackson.config.CoffeeJacksonBuilderConfig; import org.springframework.context.annotation.Import; +import com.baeldung.boot.jackson.config.CoffeeJacksonBuilderConfig; + @Import(CoffeeJacksonBuilderConfig.class) public class CoffeeJacksonBuilderIntegrationTest extends AbstractCoffeeIntegrationTest { } diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeObjectMapperIntegrationTest.java b/spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeObjectMapperIntegrationTest.java similarity index 99% rename from spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeObjectMapperIntegrationTest.java rename to spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeObjectMapperIntegrationTest.java index 34743ceba5..1226eacbf2 100644 --- a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeObjectMapperIntegrationTest.java +++ b/spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeObjectMapperIntegrationTest.java @@ -1,8 +1,9 @@ package com.baeldung.boot.jackson.app; -import com.baeldung.boot.jackson.config.CoffeeObjectMapperConfig; import org.springframework.context.annotation.Import; +import com.baeldung.boot.jackson.config.CoffeeObjectMapperConfig; + @Import(CoffeeObjectMapperConfig.class) public class CoffeeObjectMapperIntegrationTest extends AbstractCoffeeIntegrationTest { } diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeRegisterModuleIntegrationTest.java b/spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeRegisterModuleIntegrationTest.java similarity index 99% rename from spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeRegisterModuleIntegrationTest.java rename to spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeRegisterModuleIntegrationTest.java index 69bbd5be2a..38dc4a76cd 100644 --- a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/jackson/app/CoffeeRegisterModuleIntegrationTest.java +++ b/spring-boot-modules/spring-boot-data/src/test/java/com/baeldung/boot/jackson/app/CoffeeRegisterModuleIntegrationTest.java @@ -1,8 +1,9 @@ package com.baeldung.boot.jackson.app; -import com.baeldung.boot.jackson.config.CoffeeRegisterModuleConfig; import org.springframework.context.annotation.Import; +import com.baeldung.boot.jackson.config.CoffeeRegisterModuleConfig; + @Import(CoffeeRegisterModuleConfig.class) public class CoffeeRegisterModuleIntegrationTest extends AbstractCoffeeIntegrationTest { } diff --git a/spring-security-modules/spring-security-core-2/README.md b/spring-security-modules/spring-security-core-2/README.md index 80027ea42f..5f54dc1a50 100644 --- a/spring-security-modules/spring-security-core-2/README.md +++ b/spring-security-modules/spring-security-core-2/README.md @@ -8,7 +8,8 @@ This module contains articles about core Spring Security - [Prevent Cross-Site Scripting (XSS) in a Spring Application](https://www.baeldung.com/spring-prevent-xss) - [Guide to the AuthenticationManagerResolver in Spring Security](https://www.baeldung.com/spring-security-authenticationmanagerresolver) - [A Custom Spring SecurityConfigurer](https://www.baeldung.com/spring-security-custom-configurer) - +- [HttpSecurity vs. WebSecurity in Spring Security](https://www.baeldung.com/spring-security-httpsecurity-vs-websecurity) + ### Build the Project `mvn clean install` diff --git a/testing-modules/testing-libraries-2/README.md b/testing-modules/testing-libraries-2/README.md index 9e17da96a7..a37612e207 100644 --- a/testing-modules/testing-libraries-2/README.md +++ b/testing-modules/testing-libraries-2/README.md @@ -7,3 +7,4 @@ - [Gray Box Testing Using the OAT Technique](https://www.baeldung.com/java-gray-box-orthogonal-array-testing) - [Unit Testing of System.in With JUnit](https://www.baeldung.com/java-junit-testing-system-in) - [Fail Maven Build if JUnit Coverage Falls Below Certain Threshold](https://www.baeldung.com/maven-junit-fail-build-coverage-threshold) +- [How to Mock Environment Variables in Unit Tests](https://www.baeldung.com/java-unit-testing-environment-variables) diff --git a/grails/.gitignore b/web-modules/grails/.gitignore similarity index 100% rename from grails/.gitignore rename to web-modules/grails/.gitignore diff --git a/grails/README.md b/web-modules/grails/README.md similarity index 100% rename from grails/README.md rename to web-modules/grails/README.md diff --git a/grails/build.gradle b/web-modules/grails/build.gradle similarity index 100% rename from grails/build.gradle rename to web-modules/grails/build.gradle diff --git a/grails/gradle.properties b/web-modules/grails/gradle.properties similarity index 100% rename from grails/gradle.properties rename to web-modules/grails/gradle.properties diff --git a/grails/gradle/wrapper/gradle-wrapper.properties b/web-modules/grails/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from grails/gradle/wrapper/gradle-wrapper.properties rename to web-modules/grails/gradle/wrapper/gradle-wrapper.properties diff --git a/grails/gradlew b/web-modules/grails/gradlew similarity index 100% rename from grails/gradlew rename to web-modules/grails/gradlew diff --git a/grails/gradlew.bat b/web-modules/grails/gradlew.bat similarity index 100% rename from grails/gradlew.bat rename to web-modules/grails/gradlew.bat diff --git a/grails/grails-app/assets/images/apple-touch-icon-retina.png b/web-modules/grails/grails-app/assets/images/apple-touch-icon-retina.png similarity index 100% rename from grails/grails-app/assets/images/apple-touch-icon-retina.png rename to web-modules/grails/grails-app/assets/images/apple-touch-icon-retina.png diff --git a/grails/grails-app/assets/images/apple-touch-icon.png b/web-modules/grails/grails-app/assets/images/apple-touch-icon.png similarity index 100% rename from grails/grails-app/assets/images/apple-touch-icon.png rename to web-modules/grails/grails-app/assets/images/apple-touch-icon.png diff --git a/grails/grails-app/assets/images/favicon.ico b/web-modules/grails/grails-app/assets/images/favicon.ico similarity index 100% rename from grails/grails-app/assets/images/favicon.ico rename to web-modules/grails/grails-app/assets/images/favicon.ico diff --git a/grails/grails-app/assets/images/grails-cupsonly-logo-white.svg b/web-modules/grails/grails-app/assets/images/grails-cupsonly-logo-white.svg similarity index 100% rename from grails/grails-app/assets/images/grails-cupsonly-logo-white.svg rename to web-modules/grails/grails-app/assets/images/grails-cupsonly-logo-white.svg diff --git a/grails/grails-app/assets/images/grails.svg b/web-modules/grails/grails-app/assets/images/grails.svg similarity index 100% rename from grails/grails-app/assets/images/grails.svg rename to web-modules/grails/grails-app/assets/images/grails.svg diff --git a/grails/grails-app/assets/images/skin/database_add.png b/web-modules/grails/grails-app/assets/images/skin/database_add.png similarity index 100% rename from grails/grails-app/assets/images/skin/database_add.png rename to web-modules/grails/grails-app/assets/images/skin/database_add.png diff --git a/grails/grails-app/assets/images/skin/database_delete.png b/web-modules/grails/grails-app/assets/images/skin/database_delete.png similarity index 100% rename from grails/grails-app/assets/images/skin/database_delete.png rename to web-modules/grails/grails-app/assets/images/skin/database_delete.png diff --git a/grails/grails-app/assets/images/skin/database_edit.png b/web-modules/grails/grails-app/assets/images/skin/database_edit.png similarity index 100% rename from grails/grails-app/assets/images/skin/database_edit.png rename to web-modules/grails/grails-app/assets/images/skin/database_edit.png diff --git a/grails/grails-app/assets/images/skin/database_save.png b/web-modules/grails/grails-app/assets/images/skin/database_save.png similarity index 100% rename from grails/grails-app/assets/images/skin/database_save.png rename to web-modules/grails/grails-app/assets/images/skin/database_save.png diff --git a/grails/grails-app/assets/images/skin/database_table.png b/web-modules/grails/grails-app/assets/images/skin/database_table.png similarity index 100% rename from grails/grails-app/assets/images/skin/database_table.png rename to web-modules/grails/grails-app/assets/images/skin/database_table.png diff --git a/grails/grails-app/assets/images/skin/exclamation.png b/web-modules/grails/grails-app/assets/images/skin/exclamation.png similarity index 100% rename from grails/grails-app/assets/images/skin/exclamation.png rename to web-modules/grails/grails-app/assets/images/skin/exclamation.png diff --git a/grails/grails-app/assets/images/skin/house.png b/web-modules/grails/grails-app/assets/images/skin/house.png similarity index 100% rename from grails/grails-app/assets/images/skin/house.png rename to web-modules/grails/grails-app/assets/images/skin/house.png diff --git a/grails/grails-app/assets/images/skin/information.png b/web-modules/grails/grails-app/assets/images/skin/information.png similarity index 100% rename from grails/grails-app/assets/images/skin/information.png rename to web-modules/grails/grails-app/assets/images/skin/information.png diff --git a/grails/grails-app/assets/images/skin/shadow.jpg b/web-modules/grails/grails-app/assets/images/skin/shadow.jpg similarity index 100% rename from grails/grails-app/assets/images/skin/shadow.jpg rename to web-modules/grails/grails-app/assets/images/skin/shadow.jpg diff --git a/grails/grails-app/assets/images/skin/sorted_asc.gif b/web-modules/grails/grails-app/assets/images/skin/sorted_asc.gif similarity index 100% rename from grails/grails-app/assets/images/skin/sorted_asc.gif rename to web-modules/grails/grails-app/assets/images/skin/sorted_asc.gif diff --git a/grails/grails-app/assets/images/skin/sorted_desc.gif b/web-modules/grails/grails-app/assets/images/skin/sorted_desc.gif similarity index 100% rename from grails/grails-app/assets/images/skin/sorted_desc.gif rename to web-modules/grails/grails-app/assets/images/skin/sorted_desc.gif diff --git a/grails/grails-app/assets/images/spinner.gif b/web-modules/grails/grails-app/assets/images/spinner.gif similarity index 100% rename from grails/grails-app/assets/images/spinner.gif rename to web-modules/grails/grails-app/assets/images/spinner.gif diff --git a/grails/grails-app/assets/javascripts/application.js b/web-modules/grails/grails-app/assets/javascripts/application.js similarity index 100% rename from grails/grails-app/assets/javascripts/application.js rename to web-modules/grails/grails-app/assets/javascripts/application.js diff --git a/grails/grails-app/assets/javascripts/bootstrap.js b/web-modules/grails/grails-app/assets/javascripts/bootstrap.js similarity index 100% rename from grails/grails-app/assets/javascripts/bootstrap.js rename to web-modules/grails/grails-app/assets/javascripts/bootstrap.js diff --git a/grails/grails-app/assets/javascripts/jquery-2.2.0.min.js b/web-modules/grails/grails-app/assets/javascripts/jquery-2.2.0.min.js similarity index 100% rename from grails/grails-app/assets/javascripts/jquery-2.2.0.min.js rename to web-modules/grails/grails-app/assets/javascripts/jquery-2.2.0.min.js diff --git a/grails/grails-app/assets/stylesheets/application.css b/web-modules/grails/grails-app/assets/stylesheets/application.css similarity index 100% rename from grails/grails-app/assets/stylesheets/application.css rename to web-modules/grails/grails-app/assets/stylesheets/application.css diff --git a/grails/grails-app/assets/stylesheets/bootstrap.css b/web-modules/grails/grails-app/assets/stylesheets/bootstrap.css similarity index 100% rename from grails/grails-app/assets/stylesheets/bootstrap.css rename to web-modules/grails/grails-app/assets/stylesheets/bootstrap.css diff --git a/grails/grails-app/assets/stylesheets/errors.css b/web-modules/grails/grails-app/assets/stylesheets/errors.css similarity index 100% rename from grails/grails-app/assets/stylesheets/errors.css rename to web-modules/grails/grails-app/assets/stylesheets/errors.css diff --git a/grails/grails-app/assets/stylesheets/grails.css b/web-modules/grails/grails-app/assets/stylesheets/grails.css similarity index 100% rename from grails/grails-app/assets/stylesheets/grails.css rename to web-modules/grails/grails-app/assets/stylesheets/grails.css diff --git a/grails/grails-app/assets/stylesheets/main.css b/web-modules/grails/grails-app/assets/stylesheets/main.css similarity index 100% rename from grails/grails-app/assets/stylesheets/main.css rename to web-modules/grails/grails-app/assets/stylesheets/main.css diff --git a/grails/grails-app/assets/stylesheets/mobile.css b/web-modules/grails/grails-app/assets/stylesheets/mobile.css similarity index 100% rename from grails/grails-app/assets/stylesheets/mobile.css rename to web-modules/grails/grails-app/assets/stylesheets/mobile.css diff --git a/grails/grails-app/conf/application.yml b/web-modules/grails/grails-app/conf/application.yml similarity index 100% rename from grails/grails-app/conf/application.yml rename to web-modules/grails/grails-app/conf/application.yml diff --git a/grails/grails-app/conf/logback.groovy b/web-modules/grails/grails-app/conf/logback.groovy similarity index 100% rename from grails/grails-app/conf/logback.groovy rename to web-modules/grails/grails-app/conf/logback.groovy diff --git a/grails/grails-app/conf/spring/resources.groovy b/web-modules/grails/grails-app/conf/spring/resources.groovy similarity index 100% rename from grails/grails-app/conf/spring/resources.groovy rename to web-modules/grails/grails-app/conf/spring/resources.groovy diff --git a/grails/grails-app/controllers/com/baeldung/grails/StudentController.groovy b/web-modules/grails/grails-app/controllers/com/baeldung/grails/StudentController.groovy similarity index 100% rename from grails/grails-app/controllers/com/baeldung/grails/StudentController.groovy rename to web-modules/grails/grails-app/controllers/com/baeldung/grails/StudentController.groovy diff --git a/grails/grails-app/controllers/grails/UrlMappings.groovy b/web-modules/grails/grails-app/controllers/grails/UrlMappings.groovy similarity index 100% rename from grails/grails-app/controllers/grails/UrlMappings.groovy rename to web-modules/grails/grails-app/controllers/grails/UrlMappings.groovy diff --git a/grails/grails-app/domain/com/baeldung/grails/Student.groovy b/web-modules/grails/grails-app/domain/com/baeldung/grails/Student.groovy similarity index 100% rename from grails/grails-app/domain/com/baeldung/grails/Student.groovy rename to web-modules/grails/grails-app/domain/com/baeldung/grails/Student.groovy diff --git a/grails/grails-app/i18n/messages.properties b/web-modules/grails/grails-app/i18n/messages.properties similarity index 100% rename from grails/grails-app/i18n/messages.properties rename to web-modules/grails/grails-app/i18n/messages.properties diff --git a/grails/grails-app/i18n/messages_cs.properties b/web-modules/grails/grails-app/i18n/messages_cs.properties similarity index 100% rename from grails/grails-app/i18n/messages_cs.properties rename to web-modules/grails/grails-app/i18n/messages_cs.properties diff --git a/grails/grails-app/i18n/messages_da.properties b/web-modules/grails/grails-app/i18n/messages_da.properties similarity index 100% rename from grails/grails-app/i18n/messages_da.properties rename to web-modules/grails/grails-app/i18n/messages_da.properties diff --git a/grails/grails-app/i18n/messages_de.properties b/web-modules/grails/grails-app/i18n/messages_de.properties similarity index 100% rename from grails/grails-app/i18n/messages_de.properties rename to web-modules/grails/grails-app/i18n/messages_de.properties diff --git a/grails/grails-app/i18n/messages_es.properties b/web-modules/grails/grails-app/i18n/messages_es.properties similarity index 100% rename from grails/grails-app/i18n/messages_es.properties rename to web-modules/grails/grails-app/i18n/messages_es.properties diff --git a/grails/grails-app/i18n/messages_fr.properties b/web-modules/grails/grails-app/i18n/messages_fr.properties similarity index 100% rename from grails/grails-app/i18n/messages_fr.properties rename to web-modules/grails/grails-app/i18n/messages_fr.properties diff --git a/grails/grails-app/i18n/messages_it.properties b/web-modules/grails/grails-app/i18n/messages_it.properties similarity index 100% rename from grails/grails-app/i18n/messages_it.properties rename to web-modules/grails/grails-app/i18n/messages_it.properties diff --git a/grails/grails-app/i18n/messages_ja.properties b/web-modules/grails/grails-app/i18n/messages_ja.properties similarity index 100% rename from grails/grails-app/i18n/messages_ja.properties rename to web-modules/grails/grails-app/i18n/messages_ja.properties diff --git a/grails/grails-app/i18n/messages_nb.properties b/web-modules/grails/grails-app/i18n/messages_nb.properties similarity index 100% rename from grails/grails-app/i18n/messages_nb.properties rename to web-modules/grails/grails-app/i18n/messages_nb.properties diff --git a/grails/grails-app/i18n/messages_nl.properties b/web-modules/grails/grails-app/i18n/messages_nl.properties similarity index 100% rename from grails/grails-app/i18n/messages_nl.properties rename to web-modules/grails/grails-app/i18n/messages_nl.properties diff --git a/grails/grails-app/i18n/messages_pl.properties b/web-modules/grails/grails-app/i18n/messages_pl.properties similarity index 100% rename from grails/grails-app/i18n/messages_pl.properties rename to web-modules/grails/grails-app/i18n/messages_pl.properties diff --git a/grails/grails-app/i18n/messages_pt_BR.properties b/web-modules/grails/grails-app/i18n/messages_pt_BR.properties similarity index 100% rename from grails/grails-app/i18n/messages_pt_BR.properties rename to web-modules/grails/grails-app/i18n/messages_pt_BR.properties diff --git a/grails/grails-app/i18n/messages_pt_PT.properties b/web-modules/grails/grails-app/i18n/messages_pt_PT.properties similarity index 100% rename from grails/grails-app/i18n/messages_pt_PT.properties rename to web-modules/grails/grails-app/i18n/messages_pt_PT.properties diff --git a/grails/grails-app/i18n/messages_ru.properties b/web-modules/grails/grails-app/i18n/messages_ru.properties similarity index 100% rename from grails/grails-app/i18n/messages_ru.properties rename to web-modules/grails/grails-app/i18n/messages_ru.properties diff --git a/grails/grails-app/i18n/messages_sk.properties b/web-modules/grails/grails-app/i18n/messages_sk.properties similarity index 100% rename from grails/grails-app/i18n/messages_sk.properties rename to web-modules/grails/grails-app/i18n/messages_sk.properties diff --git a/grails/grails-app/i18n/messages_sv.properties b/web-modules/grails/grails-app/i18n/messages_sv.properties similarity index 100% rename from grails/grails-app/i18n/messages_sv.properties rename to web-modules/grails/grails-app/i18n/messages_sv.properties diff --git a/grails/grails-app/i18n/messages_th.properties b/web-modules/grails/grails-app/i18n/messages_th.properties similarity index 100% rename from grails/grails-app/i18n/messages_th.properties rename to web-modules/grails/grails-app/i18n/messages_th.properties diff --git a/grails/grails-app/i18n/messages_zh_CN.properties b/web-modules/grails/grails-app/i18n/messages_zh_CN.properties similarity index 100% rename from grails/grails-app/i18n/messages_zh_CN.properties rename to web-modules/grails/grails-app/i18n/messages_zh_CN.properties diff --git a/grails/grails-app/init/grails/Application.groovy b/web-modules/grails/grails-app/init/grails/Application.groovy similarity index 100% rename from grails/grails-app/init/grails/Application.groovy rename to web-modules/grails/grails-app/init/grails/Application.groovy diff --git a/grails/grails-app/init/grails/BootStrap.groovy b/web-modules/grails/grails-app/init/grails/BootStrap.groovy similarity index 100% rename from grails/grails-app/init/grails/BootStrap.groovy rename to web-modules/grails/grails-app/init/grails/BootStrap.groovy diff --git a/grails/grails-app/services/com/baeldung/grails/StudentService.groovy b/web-modules/grails/grails-app/services/com/baeldung/grails/StudentService.groovy similarity index 100% rename from grails/grails-app/services/com/baeldung/grails/StudentService.groovy rename to web-modules/grails/grails-app/services/com/baeldung/grails/StudentService.groovy diff --git a/grails/grails-app/views/error.gsp b/web-modules/grails/grails-app/views/error.gsp similarity index 100% rename from grails/grails-app/views/error.gsp rename to web-modules/grails/grails-app/views/error.gsp diff --git a/grails/grails-app/views/index.gsp b/web-modules/grails/grails-app/views/index.gsp similarity index 100% rename from grails/grails-app/views/index.gsp rename to web-modules/grails/grails-app/views/index.gsp diff --git a/grails/grails-app/views/layouts/main.gsp b/web-modules/grails/grails-app/views/layouts/main.gsp similarity index 100% rename from grails/grails-app/views/layouts/main.gsp rename to web-modules/grails/grails-app/views/layouts/main.gsp diff --git a/grails/grails-app/views/notFound.gsp b/web-modules/grails/grails-app/views/notFound.gsp similarity index 100% rename from grails/grails-app/views/notFound.gsp rename to web-modules/grails/grails-app/views/notFound.gsp diff --git a/grails/grails-app/views/student/create.gsp b/web-modules/grails/grails-app/views/student/create.gsp similarity index 100% rename from grails/grails-app/views/student/create.gsp rename to web-modules/grails/grails-app/views/student/create.gsp diff --git a/grails/grails-app/views/student/index.gsp b/web-modules/grails/grails-app/views/student/index.gsp similarity index 100% rename from grails/grails-app/views/student/index.gsp rename to web-modules/grails/grails-app/views/student/index.gsp diff --git a/grails/grails-app/views/student/show.gsp b/web-modules/grails/grails-app/views/student/show.gsp similarity index 100% rename from grails/grails-app/views/student/show.gsp rename to web-modules/grails/grails-app/views/student/show.gsp diff --git a/grails/grailsw b/web-modules/grails/grailsw similarity index 100% rename from grails/grailsw rename to web-modules/grails/grailsw diff --git a/grails/grailsw.bat b/web-modules/grails/grailsw.bat similarity index 100% rename from grails/grailsw.bat rename to web-modules/grails/grailsw.bat diff --git a/grails/src/integration-test/groovy/com/baeldung/grails/StudentIntegrationSpec.groovy b/web-modules/grails/src/integration-test/groovy/com/baeldung/grails/StudentIntegrationSpec.groovy similarity index 100% rename from grails/src/integration-test/groovy/com/baeldung/grails/StudentIntegrationSpec.groovy rename to web-modules/grails/src/integration-test/groovy/com/baeldung/grails/StudentIntegrationSpec.groovy diff --git a/grails/src/integration-test/resources/GebConfig.groovy b/web-modules/grails/src/integration-test/resources/GebConfig.groovy similarity index 100% rename from grails/src/integration-test/resources/GebConfig.groovy rename to web-modules/grails/src/integration-test/resources/GebConfig.groovy diff --git a/grails/src/test/groovy/com/baeldung/grails/StudentControllerSpec.groovy b/web-modules/grails/src/test/groovy/com/baeldung/grails/StudentControllerSpec.groovy similarity index 100% rename from grails/src/test/groovy/com/baeldung/grails/StudentControllerSpec.groovy rename to web-modules/grails/src/test/groovy/com/baeldung/grails/StudentControllerSpec.groovy diff --git a/web-modules/pom.xml b/web-modules/pom.xml index 684283b546..57810f90de 100644 --- a/web-modules/pom.xml +++ b/web-modules/pom.xml @@ -19,6 +19,7 @@ bootique dropwizard google-web-toolkit + jakarta-ee javax-servlets