네로개발일기

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

Lists in Thymelead Example

예제를 위해 Book.java 을 생성한다.

@Getter
@Setter
public class Book {

    private Long id;
    private String title;
    private String author;
}

 

Displaying List Elements

BookController.java

@GetMapping("/all")
public String showAll(Model model) {
    model.addAttribute("books", bookService.findAll());
    return "books/allBooks";
}

books/allBooks.html

<table>
  <thead>
    <tr>
      <td>Title</td>
      <td>Author</td>
    </tr>
  </thead>
    <tr th:if="${books.empty}">
      <td colspan="2">No Books Avaliable</td>
    </tr>
    <tr th:each="book : ${books}">
      <td th:text="${book.title}">Title</td>
      <td th:text="${book.author}">Author</td>
    </tr>
  <tbody>
  </tbody>
</table>

th:each 속성을 사용해서 list의 iterate 문을 사용할 수 있다.

Binding a List Using Selection Expression

@AllArgsConstructor
@Getter
@Setter
public class BooksCreationDto {
    
    private List<Book> books;
    
    public void addBook(Book book) {
        this.books.add(book);
    }
}

controller에서 List 객체를 전송하기 위해선 List 객체를 그대로 사용할 수 없다. 위와 같이 wrapper 객체를 만들어주어야 한다.

 

@GetMapping("/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 "books/createBooksForm";
}

Model 속성에 3개의 빈 Book 객체를 생성하여 추가하였다.

 

<form action="#" th:action="@{/books/save}" th:object="${form}"method="post">
    <fieldset>
        <input type="submit" id="submitButton" th:value="Save">
        <input type="reset" id="resetButton" name="reset" th:value="Reset"/>
        <table>
            <thead>
                <tr>
                    <th> Title</th>
                    <th> Author</th>
                </tr>
            </thead>
            <tbody>
                <tr th:each="book, itemStat : *{books}">
                    <td><input th:field="*{books[__${itemStat.index}__].title}" /></td>
                    <td><input th:field="*{books[__${itemStat.index}__].author}" /></td>
                </tr>
            </tbody>
        </table>
    </fieldset>
</form>

Thymeleaf를 실행하면 3개의 빈 Book 객체가 있을 것이다.

th:object="${form}"

form에서 submit을 할 때, form의 데이터가 th:object에 설정해준 객체로 받아진다.

<tr th:each="book, itemStat : *{books}">

각각 필드들을 매핑을 해주는 역할을 한다. 설정해 준 값으로, th:object에 설정해 준 객체의 내부와 매칭해준다.

@PostMapping("/save")
public String saveBooks(@ModelAttribute BooksCreationDto form, Model model) {
    bookService.saveAll(form.getBooks());

    model.addAttribute("books", bookService.findAll());
    return "redirect:/books/all";
}

@ModelAttribute 어노테이션을 활용하여 객체를 가져올 수 있다.

Book list를 저장하고 list 화면으로 redirect 해주면 다음과 같은 화면을 얻을 수 있다.

Binding a List Using Variable Expression

@GetMapping("/edit")
public String showEditForm(Model model) {
    List<Book> books = new ArrayList<>();
    bookService.findAll().iterator().forEachRemaining(books::add);

    model.addAttribute("form", new BooksCreationDto(books));
    return "books/editBooksForm";
}
<tr th:each="book, itemStat : ${form.books}">
    <td>
        <input hidden th:name="|books[${itemStat.index}].id|" th:value="${book.getId()}"/>
    </td>
    <td>
        <input th:name="|books[${itemStat.index}].title|" th:value="${book.getTitle()}"/>
    </td>
    <td>
        <input th:name="|books[${itemStat.index}].author|" th:value="${book.getAuthor()}"/>
    </td>
</tr>

적절하게 data를 submit하기 위해선 name과 value값을 지정해주어야 한다. edit 해주기 위해선 books.id도 전달해주어야 하는데, hidden 속성을 통해 보이지 않게 전달하고 있다.

 

출처

https://www.baeldung.com/thymeleaf-list

 

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !