diff --git a/spring-mvc-forms-thymeleaf/pom.xml b/spring-mvc-forms-thymeleaf/pom.xml
index 408e7643d2..59130a0133 100644
--- a/spring-mvc-forms-thymeleaf/pom.xml
+++ b/spring-mvc-forms-thymeleaf/pom.xml
@@ -69,6 +69,7 @@
UTF-8
UTF-8
3.0.9.RELEASE
+ com.baeldung.sessionattrs.SessionAttrsApplication
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Book.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Book.java
new file mode 100644
index 0000000000..823ff436fb
--- /dev/null
+++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Book.java
@@ -0,0 +1,73 @@
+package com.baeldung.listbindingexample;
+
+public class Book {
+
+ private long id;
+
+ private String title;
+
+ private String author;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((author == null) ? 0 : author.hashCode());
+ result = prime * result + (int) (id ^ (id >>> 32));
+ result = prime * result + ((title == null) ? 0 : title.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Book other = (Book) obj;
+ if (author == null) {
+ if (other.author != null)
+ return false;
+ } else if (!author.equals(other.author))
+ return false;
+ if (id != other.id)
+ return false;
+ if (title == null) {
+ if (other.title != null)
+ return false;
+ } else if (!title.equals(other.title))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "Book [id=" + id + ", title=" + title + ", author=" + author + "]";
+ }
+}
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BookService.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BookService.java
new file mode 100644
index 0000000000..770e86ad68
--- /dev/null
+++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BookService.java
@@ -0,0 +1,10 @@
+package com.baeldung.listbindingexample;
+
+import java.util.List;
+
+public interface BookService {
+
+ List findAll();
+
+ void saveAll(List books);
+}
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BooksCreationDto.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BooksCreationDto.java
new file mode 100644
index 0000000000..8e5654143a
--- /dev/null
+++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BooksCreationDto.java
@@ -0,0 +1,29 @@
+package com.baeldung.listbindingexample;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BooksCreationDto {
+
+ private List books;
+
+ public BooksCreationDto() {
+ this.books = new ArrayList<>();
+ }
+
+ public BooksCreationDto(List books) {
+ this.books = books;
+ }
+
+ public List getBooks() {
+ return books;
+ }
+
+ public void setBooks(List books) {
+ this.books = books;
+ }
+
+ public void addBook(Book book) {
+ this.books.add(book);
+ }
+}
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Config.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Config.java
new file mode 100644
index 0000000000..ffba2cea2c
--- /dev/null
+++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Config.java
@@ -0,0 +1,33 @@
+package com.baeldung.listbindingexample;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.thymeleaf.templatemode.TemplateMode;
+import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
+import org.thymeleaf.templateresolver.ITemplateResolver;
+
+@EnableWebMvc
+@Configuration
+public class Config implements WebMvcConfigurer {
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("/").setViewName("index");
+ registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
+ }
+
+ @Bean
+ public ITemplateResolver templateResolver() {
+ ClassLoaderTemplateResolver resolver
+ = new ClassLoaderTemplateResolver();
+ resolver.setPrefix("templates/books/");
+ resolver.setSuffix(".html");
+ resolver.setTemplateMode(TemplateMode.HTML);
+ resolver.setCharacterEncoding("UTF-8");
+ return resolver;
+ }
+}
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/InMemoryBookService.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/InMemoryBookService.java
new file mode 100644
index 0000000000..56ca41c51f
--- /dev/null
+++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/InMemoryBookService.java
@@ -0,0 +1,44 @@
+package com.baeldung.listbindingexample;
+
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Service
+public class InMemoryBookService implements BookService {
+
+ static Map booksDB = new HashMap<>();
+
+ @Override
+ public List findAll() {
+ return new ArrayList(booksDB.values());
+ }
+
+ @Override
+ public void saveAll(List books) {
+ long nextId = getNextId();
+ for (Book book : books) {
+ if (book.getId() == 0) {
+ book.setId(nextId++);
+ }
+ }
+
+ Map bookMap = books.stream()
+ .collect(Collectors.toMap(
+ Book::getId, Function.identity()));
+
+ booksDB.putAll(bookMap);
+ }
+
+ private Long getNextId(){
+ return booksDB.keySet().stream()
+ .mapToLong(value -> value)
+ .max()
+ .orElse(0) + 1;
+ }
+}
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/ListBindingApplication.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/ListBindingApplication.java
new file mode 100644
index 0000000000..af8608704b
--- /dev/null
+++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/ListBindingApplication.java
@@ -0,0 +1,16 @@
+package com.baeldung.listbindingexample;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
+
+@SpringBootApplication(
+ exclude = {SecurityAutoConfiguration.class,
+ DataSourceAutoConfiguration.class})
+public class ListBindingApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ListBindingApplication.class, args);
+ }
+}
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/MultipleBooksController.java b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/MultipleBooksController.java
new file mode 100644
index 0000000000..2e177c7bbf
--- /dev/null
+++ b/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/MultipleBooksController.java
@@ -0,0 +1,59 @@
+package com.baeldung.listbindingexample;
+
+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.ModelAttribute;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Controller
+@RequestMapping("/books")
+public class MultipleBooksController {
+
+ @Autowired
+ private BookService bookService;
+
+ @GetMapping(value = "/all")
+ public String showAll(Model model) {
+ model.addAttribute("books", bookService.findAll());
+
+ return "allBooks";
+ }
+
+ @GetMapping(value = "/create")
+ public String showCreateForm(Model model) {
+ BooksCreationDto booksForm = new BooksCreationDto();
+
+ for (int i = 1; i <= 3; i++) {
+ booksForm.addBook(new Book());
+ }
+
+ model.addAttribute("form", booksForm);
+
+ return "createBooksForm";
+ }
+
+ @GetMapping(value = "/edit")
+ public String showEditForm(Model model) {
+ List books = new ArrayList<>();
+ bookService.findAll().iterator().forEachRemaining(books::add);
+
+ model.addAttribute("form", new BooksCreationDto(books));
+
+ return "editBooksForm";
+ }
+
+ @PostMapping(value = "/save")
+ public String saveBooks(@ModelAttribute BooksCreationDto form, Model model) {
+ bookService.saveAll(form.getBooks());
+
+ model.addAttribute("books", bookService.findAll());
+
+ return "redirect:/books/all";
+ }
+}
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/allBooks.html b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/allBooks.html
new file mode 100644
index 0000000000..9f75bec8bd
--- /dev/null
+++ b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/allBooks.html
@@ -0,0 +1,40 @@
+
+
+ All Books
+
+
+
+
+
+
+
+
+
+
+ | Title |
+ Author |
+
+
+
+
+ | No Books Available |
+
+
+ | Title |
+ Author |
+
+
+
+
+
+
+
+
+
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/createBooksForm.html b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/createBooksForm.html
new file mode 100644
index 0000000000..9f88762882
--- /dev/null
+++ b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/createBooksForm.html
@@ -0,0 +1,45 @@
+
+
+ Add Books
+
+
+
+
+
+
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/editBooksForm.html b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/editBooksForm.html
new file mode 100644
index 0000000000..9278d98018
--- /dev/null
+++ b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/editBooksForm.html
@@ -0,0 +1,49 @@
+
+
+ Edit Books
+
+
+
+
+
+
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/index.html b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/index.html
new file mode 100644
index 0000000000..59780b84aa
--- /dev/null
+++ b/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/index.html
@@ -0,0 +1,22 @@
+
+
+
+ Binding a List in Thymeleaf
+
+
+
+
+
+
+
+
+
+
Binding a List in Thymeleaf - Example
+
+
+
+
+