From ff67d378b0b30fbd18097107483351824cddf723 Mon Sep 17 00:00:00 2001
From: chaos2418 <>
Date: Sat, 18 Dec 2021 17:40:12 +0530
Subject: [PATCH] JAVA-8281: split or move spring-thymeleaf module
---
spring-web-modules/pom.xml | 1 +
.../spring-thymeleaf-3/README.md | 1 +
.../spring-thymeleaf-4/README.md | 26 ++++
spring-web-modules/spring-thymeleaf-4/pom.xml | 131 ++++++++++++++++++
.../com/baeldung/thymeleaf/config/WebApp.java | 36 +++++
.../thymeleaf/config/WebMVCConfig.java | 115 +++++++++++++++
.../thymeleaf/controller/BookController.java | 14 +-
.../thymeleaf/controller/HomeController.java | 8 +-
.../controller/StudentController.java | 10 +-
.../controller/TeacherController.java | 3 +-
.../thymeleaf/formatter/NameFormatter.java | 30 ++++
.../com/baeldung/thymeleaf/model/Book.java | 0
.../com/baeldung/thymeleaf/model/Student.java | 59 ++++++++
.../com/baeldung/thymeleaf/model/Teacher.java | 7 +-
.../thymeleaf/service/BookService.java | 9 +-
.../baeldung/thymeleaf/utils/ArrayUtil.java | 8 ++
.../baeldung/thymeleaf/utils/BookUtils.java | 4 +-
.../thymeleaf/utils/StudentUtils.java | 34 +++++
.../thymeleaf/utils/TeacherUtils.java | 4 +-
.../src/main/resources/logback.xml | 19 +++
.../src/main/resources/messages_en.properties | 13 ++
.../main/webapp/WEB-INF/views/addStudent.html | 0
.../src/main/webapp/WEB-INF/views/home.html | 0
.../main/webapp/WEB-INF/views/listBooks.html | 0
.../webapp/WEB-INF/views/listStudents.html | 0
.../webapp/WEB-INF/views/listTeachers.html | 0
.../baeldung/thymeleaf/SpringContextTest.java | 19 +++
spring-web-modules/spring-thymeleaf/README.md | 11 --
28 files changed, 518 insertions(+), 44 deletions(-)
create mode 100644 spring-web-modules/spring-thymeleaf-4/README.md
create mode 100644 spring-web-modules/spring-thymeleaf-4/pom.xml
create mode 100644 spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/config/WebApp.java
create mode 100644 spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/java/com/baeldung/thymeleaf/controller/BookController.java (99%)
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/java/com/baeldung/thymeleaf/controller/HomeController.java (100%)
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/java/com/baeldung/thymeleaf/controller/StudentController.java (99%)
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/java/com/baeldung/thymeleaf/controller/TeacherController.java (99%)
create mode 100644 spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/formatter/NameFormatter.java
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/java/com/baeldung/thymeleaf/model/Book.java (100%)
create mode 100644 spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/model/Student.java
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/java/com/baeldung/thymeleaf/model/Teacher.java (99%)
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/java/com/baeldung/thymeleaf/service/BookService.java (99%)
create mode 100644 spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/ArrayUtil.java
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/java/com/baeldung/thymeleaf/utils/BookUtils.java (100%)
create mode 100644 spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/StudentUtils.java
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/java/com/baeldung/thymeleaf/utils/TeacherUtils.java (100%)
create mode 100644 spring-web-modules/spring-thymeleaf-4/src/main/resources/logback.xml
create mode 100644 spring-web-modules/spring-thymeleaf-4/src/main/resources/messages_en.properties
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/webapp/WEB-INF/views/addStudent.html (100%)
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/webapp/WEB-INF/views/home.html (100%)
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/webapp/WEB-INF/views/listBooks.html (100%)
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/webapp/WEB-INF/views/listStudents.html (100%)
rename spring-web-modules/{spring-thymeleaf => spring-thymeleaf-4}/src/main/webapp/WEB-INF/views/listTeachers.html (100%)
create mode 100644 spring-web-modules/spring-thymeleaf-4/src/test/java/com/baeldung/thymeleaf/SpringContextTest.java
diff --git a/spring-web-modules/pom.xml b/spring-web-modules/pom.xml
index b84ea5a13a..cc54a9132b 100644
--- a/spring-web-modules/pom.xml
+++ b/spring-web-modules/pom.xml
@@ -44,6 +44,7 @@
spring-thymeleaf
spring-thymeleaf-2
spring-thymeleaf-3
+ spring-thymeleaf-4
spring-boot-jsp
spring-web-url
diff --git a/spring-web-modules/spring-thymeleaf-3/README.md b/spring-web-modules/spring-thymeleaf-3/README.md
index 76c54d3885..46ddd6c03f 100644
--- a/spring-web-modules/spring-thymeleaf-3/README.md
+++ b/spring-web-modules/spring-thymeleaf-3/README.md
@@ -11,3 +11,4 @@ This module contains articles about Spring with Thymeleaf
- [Using Hidden Inputs with Spring and Thymeleaf](https://www.baeldung.com/spring-thymeleaf-hidden-inputs)
- [Thymeleaf Variables](https://www.baeldung.com/thymeleaf-variables)
- [Displaying Error Messages with Thymeleaf in Spring](https://www.baeldung.com/spring-thymeleaf-error-messages)
+- [[next -->]](/spring-thymeleaf-4)
diff --git a/spring-web-modules/spring-thymeleaf-4/README.md b/spring-web-modules/spring-thymeleaf-4/README.md
new file mode 100644
index 0000000000..2ed70f1c49
--- /dev/null
+++ b/spring-web-modules/spring-thymeleaf-4/README.md
@@ -0,0 +1,26 @@
+## Spring Thymeleaf
+
+This module contains articles about Spring with Thymeleaf
+
+### Relevant Articles:
+- [Conditionals in Thymeleaf](https://www.baeldung.com/spring-thymeleaf-conditionals)
+- [Iteration in Thymeleaf](https://www.baeldung.com/thymeleaf-iteration)
+- [Spring with Thymeleaf Pagination for a List](https://www.baeldung.com/spring-thymeleaf-pagination)
+
+### Build the Project
+
+mvn clean install
+
+### Run the Project
+
+mvn cargo:run
+- **note**: starts on port '8082'
+
+Access the pages using the URLs:
+
+ - http://localhost:8082/spring-thymeleaf-4/
+ - http://localhost:8082/spring-thymeleaf-4/addStudent/
+ - http://localhost:8082/spring-thymeleaf-4/listStudents/
+
+The first URL is the home page of the application. The home page has links to the second and third pages.
+
diff --git a/spring-web-modules/spring-thymeleaf-4/pom.xml b/spring-web-modules/spring-thymeleaf-4/pom.xml
new file mode 100644
index 0000000000..f307e6fc26
--- /dev/null
+++ b/spring-web-modules/spring-thymeleaf-4/pom.xml
@@ -0,0 +1,131 @@
+
+
+ 4.0.0
+ spring-thymeleaf-4
+ spring-thymeleaf-4
+ war
+
+
+ com.baeldung
+ parent-spring-5
+ 0.0.1-SNAPSHOT
+ ../../parent-spring-5
+
+
+
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+ org.springframework
+ spring-webmvc
+ ${spring.version}
+
+
+ org.springframework.data
+ spring-data-commons
+ ${spring-data.version}
+
+
+ javax.validation
+ validation-api
+ ${javax.validation-version}
+
+
+ org.hibernate.validator
+ hibernate-validator
+ ${hibernate-validator.version}
+
+
+
+ org.thymeleaf
+ thymeleaf
+ ${org.thymeleaf-version}
+
+
+ org.thymeleaf
+ thymeleaf-spring5
+ ${org.thymeleaf-version}
+
+
+ nz.net.ultraq.thymeleaf
+ thymeleaf-layout-dialect
+ ${thymeleaf-layout-dialect.version}
+
+
+ org.thymeleaf.extras
+ thymeleaf-extras-java8time
+ ${org.thymeleaf.extras-version}
+
+
+
+ javax.servlet
+ javax.servlet-api
+ ${javax.servlet-api.version}
+ provided
+
+
+
+ org.springframework
+ spring-test
+ ${spring.version}
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ ${maven-war-plugin.version}
+
+ false
+
+
+
+ org.codehaus.cargo
+ cargo-maven2-plugin
+ ${cargo-maven2-plugin.version}
+
+ true
+
+ jetty9x
+ embedded
+
+
+
+
+
+ 8082
+
+
+
+
+
+
+
+
+ 2.3.2.RELEASE
+ 3.0.11.RELEASE
+ 3.0.4.RELEASE
+ 2.4.1
+ 2.0.1.Final
+ 6.0.11.Final
+
+ 1.6.1
+
+
+
\ No newline at end of file
diff --git a/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/config/WebApp.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/config/WebApp.java
new file mode 100644
index 0000000000..0913152bc3
--- /dev/null
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/config/WebApp.java
@@ -0,0 +1,36 @@
+package com.baeldung.thymeleaf.config;
+
+import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
+
+import javax.servlet.ServletRegistration.Dynamic;
+
+/**
+ * Java configuration file that is used for web application initialization
+ */
+public class WebApp extends AbstractAnnotationConfigDispatcherServletInitializer {
+
+ public WebApp() {
+ super();
+ }
+
+ @Override
+ protected Class>[] getRootConfigClasses() {
+ return null;
+ }
+
+ @Override
+ protected Class>[] getServletConfigClasses() {
+ return new Class>[] { WebMVCConfig.class };
+ }
+
+ @Override
+ protected String[] getServletMappings() {
+ return new String[] { "/" };
+ }
+
+ @Override
+ protected void customizeRegistration(final Dynamic registration) {
+ super.customizeRegistration(registration);
+ }
+
+}
diff --git a/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java
new file mode 100644
index 0000000000..50a555a017
--- /dev/null
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java
@@ -0,0 +1,115 @@
+package com.baeldung.thymeleaf.config;
+
+import com.baeldung.thymeleaf.formatter.NameFormatter;
+import com.baeldung.thymeleaf.utils.ArrayUtil;
+import nz.net.ultraq.thymeleaf.LayoutDialect;
+import nz.net.ultraq.thymeleaf.decorators.strategies.GroupingStrategy;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Description;
+import org.springframework.context.support.ResourceBundleMessageSource;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
+import org.springframework.web.servlet.i18n.SessionLocaleResolver;
+import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect;
+import org.thymeleaf.spring5.ISpringTemplateEngine;
+import org.thymeleaf.spring5.SpringTemplateEngine;
+import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
+import org.thymeleaf.spring5.view.ThymeleafViewResolver;
+import org.thymeleaf.templatemode.TemplateMode;
+import org.thymeleaf.templateresolver.ITemplateResolver;
+
+import java.util.Locale;
+
+@Configuration
+@EnableWebMvc
+@ComponentScan({ "com.baeldung.thymeleaf" })
+/*
+ Java configuration file that is used for Spring MVC and Thymeleaf
+ configurations
+ */
+public class WebMVCConfig implements WebMvcConfigurer, ApplicationContextAware {
+
+ private ApplicationContext applicationContext;
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) {
+ this.applicationContext = applicationContext;
+ }
+
+ @Bean
+ public ViewResolver htmlViewResolver() {
+ ThymeleafViewResolver resolver = new ThymeleafViewResolver();
+ resolver.setTemplateEngine(templateEngine(htmlTemplateResolver()));
+ resolver.setContentType("text/html");
+ resolver.setCharacterEncoding("UTF-8");
+ resolver.setViewNames(ArrayUtil.array("*.html"));
+ return resolver;
+ }
+
+ private ISpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
+ SpringTemplateEngine engine = new SpringTemplateEngine();
+ engine.addDialect(new LayoutDialect(new GroupingStrategy()));
+ engine.addDialect(new Java8TimeDialect());
+ engine.setTemplateResolver(templateResolver);
+ engine.setTemplateEngineMessageSource(messageSource());
+ return engine;
+ }
+
+ private ITemplateResolver htmlTemplateResolver() {
+ SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
+ resolver.setApplicationContext(applicationContext);
+ resolver.setPrefix("/WEB-INF/views/");
+ resolver.setCacheable(false);
+ resolver.setTemplateMode(TemplateMode.HTML);
+ return resolver;
+ }
+
+ @Bean
+ @Description("Spring Message Resolver")
+ public ResourceBundleMessageSource messageSource() {
+ ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
+ messageSource.setBasename("messages");
+ return messageSource;
+ }
+
+ @Bean
+ public LocaleResolver localeResolver() {
+ SessionLocaleResolver localeResolver = new SessionLocaleResolver();
+ localeResolver.setDefaultLocale(new Locale("en"));
+ return localeResolver;
+ }
+
+ @Bean
+ public LocaleChangeInterceptor localeChangeInterceptor() {
+ LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
+ localeChangeInterceptor.setParamName("lang");
+ return localeChangeInterceptor;
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(localeChangeInterceptor());
+ }
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/resources/**", "/css/**")
+ .addResourceLocations("/WEB-INF/resources/", "/WEB-INF/css/");
+ }
+
+ @Override
+ @Description("Custom Conversion Service")
+ public void addFormatters(FormatterRegistry registry) {
+ registry.addFormatter(new NameFormatter());
+ }
+}
diff --git a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/BookController.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/controller/BookController.java
similarity index 99%
rename from spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/BookController.java
rename to spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/controller/BookController.java
index d10caee9e7..194bf5825f 100644
--- a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/BookController.java
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/controller/BookController.java
@@ -1,22 +1,20 @@
package com.baeldung.thymeleaf.controller;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
+import com.baeldung.thymeleaf.model.Book;
+import com.baeldung.thymeleaf.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
-
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
-import com.baeldung.thymeleaf.model.Book;
-import com.baeldung.thymeleaf.service.BookService;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
@Controller
public class BookController {
diff --git a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/HomeController.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/controller/HomeController.java
similarity index 100%
rename from spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/HomeController.java
rename to spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/controller/HomeController.java
index 21f230c84c..8bbcd8fdb7 100644
--- a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/HomeController.java
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/controller/HomeController.java
@@ -1,14 +1,14 @@
package com.baeldung.thymeleaf.controller;
-import java.text.DateFormat;
-import java.util.Date;
-import java.util.Locale;
-
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Locale;
+
/**
* Handles requests for the application home page.
*
diff --git a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/StudentController.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/controller/StudentController.java
similarity index 99%
rename from spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/StudentController.java
rename to spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/controller/StudentController.java
index 77cf02c902..99dd5501ae 100644
--- a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/StudentController.java
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/controller/StudentController.java
@@ -1,9 +1,7 @@
package com.baeldung.thymeleaf.controller;
-import java.util.List;
-
-import javax.validation.Valid;
-
+import com.baeldung.thymeleaf.model.Student;
+import com.baeldung.thymeleaf.utils.StudentUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
@@ -11,8 +9,8 @@ import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
-import com.baeldung.thymeleaf.model.Student;
-import com.baeldung.thymeleaf.utils.StudentUtils;
+import javax.validation.Valid;
+import java.util.List;
/**
* Handles requests for the student model.
diff --git a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/TeacherController.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/controller/TeacherController.java
similarity index 99%
rename from spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/TeacherController.java
rename to spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/controller/TeacherController.java
index 844d746084..c3a106f11a 100644
--- a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/TeacherController.java
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/controller/TeacherController.java
@@ -1,12 +1,11 @@
package com.baeldung.thymeleaf.controller;
+import com.baeldung.thymeleaf.utils.TeacherUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
-import com.baeldung.thymeleaf.utils.TeacherUtils;
-
@Controller
public class TeacherController {
diff --git a/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/formatter/NameFormatter.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/formatter/NameFormatter.java
new file mode 100644
index 0000000000..5fd5e88651
--- /dev/null
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/formatter/NameFormatter.java
@@ -0,0 +1,30 @@
+package com.baeldung.thymeleaf.formatter;
+
+import org.springframework.format.Formatter;
+import org.thymeleaf.util.StringUtils;
+
+import java.text.ParseException;
+import java.util.Locale;
+
+/**
+ *
+ * Name formatter class that implements the Spring Formatter interface.
+ * Formats a name(String) and return the value with spaces replaced by commas.
+ *
+ */
+public class NameFormatter implements Formatter {
+
+ @Override
+ public String print(String input, Locale locale) {
+ return formatName(input, locale);
+ }
+
+ @Override
+ public String parse(String input, Locale locale) throws ParseException {
+ return formatName(input, locale);
+ }
+
+ private String formatName(String input, Locale locale) {
+ return StringUtils.replace(input, " ", ",");
+ }
+}
diff --git a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Book.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/model/Book.java
similarity index 100%
rename from spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Book.java
rename to spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/model/Book.java
diff --git a/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/model/Student.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/model/Student.java
new file mode 100644
index 0000000000..ca76cec986
--- /dev/null
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/model/Student.java
@@ -0,0 +1,59 @@
+package com.baeldung.thymeleaf.model;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ *
+ * Simple student POJO with few fields
+ *
+ */
+public class Student implements Serializable {
+
+ private static final long serialVersionUID = -8582553475226281591L;
+
+ @NotNull(message = "Student ID is required.")
+ @Min(value = 1000, message = "Student ID must be at least 4 digits.")
+ private Integer id;
+
+ @NotNull(message = "Student name is required.")
+ private String name;
+
+ @NotNull(message = "Student gender is required.")
+ private Character gender;
+
+ private Float percentage;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Character getGender() {
+ return gender;
+ }
+
+ public void setGender(Character gender) {
+ this.gender = gender;
+ }
+
+ public Float getPercentage() {
+ return percentage;
+ }
+
+ public void setPercentage(Float percentage) {
+ this.percentage = percentage;
+ }
+}
diff --git a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Teacher.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/model/Teacher.java
similarity index 99%
rename from spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Teacher.java
rename to spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/model/Teacher.java
index ad43590818..62f8a2938a 100644
--- a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Teacher.java
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/model/Teacher.java
@@ -1,11 +1,10 @@
package com.baeldung.thymeleaf.model;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
public class Teacher implements Serializable {
diff --git a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/service/BookService.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/service/BookService.java
similarity index 99%
rename from spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/service/BookService.java
rename to spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/service/BookService.java
index 2aaa559251..a330a924bd 100644
--- a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/service/BookService.java
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/service/BookService.java
@@ -1,16 +1,15 @@
package com.baeldung.thymeleaf.service;
-import java.util.Collections;
-import java.util.List;
-
+import com.baeldung.thymeleaf.model.Book;
+import com.baeldung.thymeleaf.utils.BookUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
-import com.baeldung.thymeleaf.model.Book;
-import com.baeldung.thymeleaf.utils.BookUtils;
+import java.util.Collections;
+import java.util.List;
@Service
public class BookService {
diff --git a/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/ArrayUtil.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/ArrayUtil.java
new file mode 100644
index 0000000000..5c07476c9b
--- /dev/null
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/ArrayUtil.java
@@ -0,0 +1,8 @@
+package com.baeldung.thymeleaf.utils;
+
+public class ArrayUtil {
+
+ public static String[] array(String... args) {
+ return args;
+ }
+}
\ No newline at end of file
diff --git a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/utils/BookUtils.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/BookUtils.java
similarity index 100%
rename from spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/utils/BookUtils.java
rename to spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/BookUtils.java
index 3cd9e6a92e..0a23a1bdba 100644
--- a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/utils/BookUtils.java
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/BookUtils.java
@@ -1,11 +1,11 @@
package com.baeldung.thymeleaf.utils;
+import com.baeldung.thymeleaf.model.Book;
+
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
-import com.baeldung.thymeleaf.model.Book;
-
public class BookUtils {
private static List books = new ArrayList();
diff --git a/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/StudentUtils.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/StudentUtils.java
new file mode 100644
index 0000000000..0e1165333d
--- /dev/null
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/StudentUtils.java
@@ -0,0 +1,34 @@
+package com.baeldung.thymeleaf.utils;
+
+import com.baeldung.thymeleaf.model.Student;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class StudentUtils {
+
+ private static List students = new ArrayList();
+
+ public static List buildStudents() {
+ if (students.isEmpty()) {
+ Student student1 = new Student();
+ student1.setId(1001);
+ student1.setName("John Smith");
+ student1.setGender('M');
+ student1.setPercentage(Float.valueOf("80.45"));
+
+ students.add(student1);
+
+ Student student2 = new Student();
+ student2.setId(1002);
+ student2.setName("Jane Williams");
+ student2.setGender('F');
+ student2.setPercentage(Float.valueOf("60.25"));
+
+ students.add(student2);
+ }
+
+ return students;
+ }
+
+}
diff --git a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/utils/TeacherUtils.java b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/TeacherUtils.java
similarity index 100%
rename from spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/utils/TeacherUtils.java
rename to spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/TeacherUtils.java
index 1bb279cc92..f4b759e9df 100644
--- a/spring-web-modules/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/utils/TeacherUtils.java
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/java/com/baeldung/thymeleaf/utils/TeacherUtils.java
@@ -1,10 +1,10 @@
package com.baeldung.thymeleaf.utils;
+import com.baeldung.thymeleaf.model.Teacher;
+
import java.util.ArrayList;
import java.util.List;
-import com.baeldung.thymeleaf.model.Teacher;
-
public class TeacherUtils {
private static List teachers = new ArrayList();
diff --git a/spring-web-modules/spring-thymeleaf-4/src/main/resources/logback.xml b/spring-web-modules/spring-thymeleaf-4/src/main/resources/logback.xml
new file mode 100644
index 0000000000..56af2d397e
--- /dev/null
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/resources/logback.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-web-modules/spring-thymeleaf-4/src/main/resources/messages_en.properties b/spring-web-modules/spring-thymeleaf-4/src/main/resources/messages_en.properties
new file mode 100644
index 0000000000..b534d448b6
--- /dev/null
+++ b/spring-web-modules/spring-thymeleaf-4/src/main/resources/messages_en.properties
@@ -0,0 +1,13 @@
+msg.id=ID
+msg.name=Name
+msg.gender=Gender
+msg.percent=Percentage
+welcome.message=Welcome Student !!!
+msg.AddStudent=Add Student
+msg.ListStudents=List Students
+msg.Home=Home
+msg.ListTeachers=List Teachers
+msg.ListBooks=List Books with paging
+msg.courses=Courses
+msg.skills=Skills
+msg.active=Active
\ No newline at end of file
diff --git a/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/addStudent.html b/spring-web-modules/spring-thymeleaf-4/src/main/webapp/WEB-INF/views/addStudent.html
similarity index 100%
rename from spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/addStudent.html
rename to spring-web-modules/spring-thymeleaf-4/src/main/webapp/WEB-INF/views/addStudent.html
diff --git a/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/home.html b/spring-web-modules/spring-thymeleaf-4/src/main/webapp/WEB-INF/views/home.html
similarity index 100%
rename from spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/home.html
rename to spring-web-modules/spring-thymeleaf-4/src/main/webapp/WEB-INF/views/home.html
diff --git a/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/listBooks.html b/spring-web-modules/spring-thymeleaf-4/src/main/webapp/WEB-INF/views/listBooks.html
similarity index 100%
rename from spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/listBooks.html
rename to spring-web-modules/spring-thymeleaf-4/src/main/webapp/WEB-INF/views/listBooks.html
diff --git a/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/listStudents.html b/spring-web-modules/spring-thymeleaf-4/src/main/webapp/WEB-INF/views/listStudents.html
similarity index 100%
rename from spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/listStudents.html
rename to spring-web-modules/spring-thymeleaf-4/src/main/webapp/WEB-INF/views/listStudents.html
diff --git a/spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/listTeachers.html b/spring-web-modules/spring-thymeleaf-4/src/main/webapp/WEB-INF/views/listTeachers.html
similarity index 100%
rename from spring-web-modules/spring-thymeleaf/src/main/webapp/WEB-INF/views/listTeachers.html
rename to spring-web-modules/spring-thymeleaf-4/src/main/webapp/WEB-INF/views/listTeachers.html
diff --git a/spring-web-modules/spring-thymeleaf-4/src/test/java/com/baeldung/thymeleaf/SpringContextTest.java b/spring-web-modules/spring-thymeleaf-4/src/test/java/com/baeldung/thymeleaf/SpringContextTest.java
new file mode 100644
index 0000000000..e2708330f2
--- /dev/null
+++ b/spring-web-modules/spring-thymeleaf-4/src/test/java/com/baeldung/thymeleaf/SpringContextTest.java
@@ -0,0 +1,19 @@
+package com.baeldung.thymeleaf;
+
+import com.baeldung.thymeleaf.config.WebApp;
+import com.baeldung.thymeleaf.config.WebMVCConfig;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@WebAppConfiguration
+@ContextConfiguration(classes = { WebApp.class, WebMVCConfig.class })
+public class SpringContextTest {
+
+ @Test
+ public void whenSpringContextIsBootstrapped_thenNoExceptions() {
+ }
+}
diff --git a/spring-web-modules/spring-thymeleaf/README.md b/spring-web-modules/spring-thymeleaf/README.md
index 7c3d4cafa3..e83ef332e0 100644
--- a/spring-web-modules/spring-thymeleaf/README.md
+++ b/spring-web-modules/spring-thymeleaf/README.md
@@ -10,9 +10,6 @@ This module contains articles about Spring with Thymeleaf
- [Spring MVC + Thymeleaf 3.0: New Features](https://www.baeldung.com/spring-thymeleaf-3)
- [How to Work with Dates in Thymeleaf](https://www.baeldung.com/dates-in-thymeleaf)
- [Working with Fragments in Thymeleaf](https://www.baeldung.com/spring-thymeleaf-fragments)
-- [Conditionals in Thymeleaf](https://www.baeldung.com/spring-thymeleaf-conditionals)
-- [Iteration in Thymeleaf](https://www.baeldung.com/thymeleaf-iteration)
-- [Spring with Thymeleaf Pagination for a List](https://www.baeldung.com/spring-thymeleaf-pagination)
- [[next -->]](/spring-thymeleaf-2)
### Build the Project
@@ -24,13 +21,5 @@ mvn clean install
mvn cargo:run
- **note**: starts on port '8082'
-Access the pages using the URLs:
-
- - http://localhost:8082/spring-thymeleaf/
- - http://localhost:8082/spring-thymeleaf/addStudent/
- - http://localhost:8082/spring-thymeleaf/listStudents/
-
-The first URL is the home page of the application. The home page has links to the second and third pages.
-
### Security
The user/password required is: user1/user1Pass