Spring Boot Thymeleaf example
Thymeleaf
is a Java XML/XHTML/HTML5 template engine that works in both web (servlet-based) and non-web environments. In web applications Thymeleaf
aims to be a complete substitute for JavaServer Pages (JSP).Thymeleaf
is ideal for modern-day HTML5 JVM web development.
This Spring Boot Thymeleaf
example shows how to create a view using Thymeleaf
as template engine in a Spring Boot application
.
Step 1) Create pom.xml
Add spring-boot-starter-thymeleaf as a dependency in pom.xml file to get the desired Thymeleaf dependencies. Using above Spring Boot will configure the ThymeleafViewResolver automatically.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
Step 2) Create StudentsApplication class
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class StudentsApplication { public static void main(String[] args) { SpringApplication.run(StudentsApplication.class, args); } }
Step 3) Create index.html file and put it under src/main/resources/templates directory
index.html is a HTML5 page which serves as the home page for StudentsApplication
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Spring Boot Thymeleaf example</title> </head> <body> <h1>List of Students</h1> <a th:href="@{/students}" href="#">Click here to view list of Students</a> </body> </html>
Step 4) Create students.html file and put it under src/main/resources/templates directory
students.html is a HTML5 page which prints the list of all students
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"></html> <head> <meta charset="UTF-8"> <title>Spring Boot Thymeleaf example</title> </head> <body> <h1>List of Students</h1> <table> <thead> <tr> <th>Roll Number</th> <th>First Name</th> <th>Last Name</th> </tr> </thead> <tbody> <tr th:each="student: ${students}"> <td th:text ="${student.rollNumber}">Roll Number</td> <td th:text ="${student.firstName}">First Name</td> <td th:text ="${student.lastName}">Last Name</td> </tr> </tbody> </table> </body>
Step 5) Create Student StudentsService, StudentsServiceImpl classes
Student class will be used as model by the Students application, StudentsService class will be used as service by controller.
package com.example.demo; public class Student { private String rollNumber; private String firstName; private String lastName; public Student(String rollNumber, String firstName, String lastName) { this.rollNumber = rollNumber; this.firstName = firstName; this.lastName = lastName; } // removed getter and setter for brevity @Override public String toString() { return "Student [rollNumber=" + rollNumber + ", firstName=" + firstName + ", lastName=" + lastName + "]"; } }
package com.example.demo; import java.util.Collection; public interface StudentsService { Collection<Student> getAll(); Student create(Student user); }
package com.example.demo; import java.util.Collection; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.springframework.stereotype.Service; @Service public class StudentsServiceImpl implements StudentsService { private final Map<String, Student> students = new ConcurrentHashMap<>(); public StudentsServiceImpl() { students.put("123", new Student("123", "Robert", "Downey")); students.put("124", new Student("124", "Christian", "Bale")); students.put("125", new Student("125", "Henry", "Cavil")); } @Override public Collection<Student> getAll() { return students.values(); } @Override public Student create(Student student) { students.put(student.getRollNumber(), student); return student; } }
Step 6) Create StudentsController class
getAllStudents() will populate the model with the list of all students and returns the view name.
package com.example.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class StudentsController { @Autowired private StudentsService studentsService; @RequestMapping(value = "/index") public String index() { return "index"; } @GetMapping("/students") public String getAllStudents(Model model) { model.addAttribute("students", studentsService.getAll()); System.out.println(model); return "students"; } @PostMapping() public Student create(@RequestBody Student student) { return studentsService.create(student); } }
Directory structure
Step 7) Run StudentsApplication
Console Output :
2019-11-30 21:00:08.555 INFO 3096 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2019-11-30 21:00:08.602 INFO 3096 --- [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2019-11-30 21:00:08.602 INFO 3096 --- [main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.21] 2019-11-30 21:00:08.758 INFO 3096 --- [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2019-11-30 21:00:08.758 INFO 3096 --- [main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2981 ms 2019-11-30 21:00:09.139 INFO 3096 --- [main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2019-11-30 21:00:09.381 INFO 3096 --- [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index 2019-11-30 21:00:09.529 INFO 3096 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2019-11-30 21:00:09.529 INFO 3096 --- [main] com.example.demo.StudentsApplication : Started StudentsApplication in 4.569 seconds (JVM running for 5.058) 2019-11-30 21:00:09.824 INFO 3096 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2019-11-30 21:00:09.824 INFO 3096 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2019-11-30 21:00:09.910 INFO 3096 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 86 ms 2019-11-30 21:00:09.958 WARN 3096 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported] {students=[Student [id=123, firstName=Robert, lasttName=Downey], Student [id=124, firstName=Christian, lasttName=Bale], Student [id=125, firstName=Henry, lasttName=Cavill]]}
Step 8) Testing StudentsApplication
Open any browser and launch http://localhost:8080/index You will see below page.Click on the hyperlink which will navigate the user to http://localhost:8080/students. You will see below page.
References :
Thymeleaf