Post

Thymeleaf 와 Spring 통합

Thymeleaf 와 Spring 연동 방법

Spring 에서 타임리프를 사용하려면 타임리프 템플릿 엔진을 스프링 빈에 등록하고, 타임리프용 viewResolver 를 스프링 빈으로 등록해야 한다. (링크)

하지만, SpringBoot 는 spring-boot-starter-thymeleaf 라이브러리만 추가하면 자동으로 설정해준다.

<form> 태그와 attribute 바인딩

1
2
3
4
5
6
7
8
9
10
<form th:object="${item}">
    <!-- <input type="text" th:field="${item.itemName}"/> -->
    <input type="text" th:field="*{itemName}"/>
    <input type="text" th:field="*{price}"/>
    <input type="text" th:field="*{quantity}"/>

    <input type="checkbox" th:field="*{open}"/>
    <input type="radio" th:field="*{itemType}"/>
    <select th:field="*{deliveryCode}"></select>
</form>
  • <form> 태그에 th:object 를 적용하고 model에 담긴 attribute 객체를 할당해준다.
  • <input> 태그에 th:field 를 사용하면 attribute 객체의 값을 자동으로 바인딩해주고 id, name, value 속성을 자동으로 생성해준다.
  • 부모 태그에 th:object 가 있다면 ${item.itemName}*{itemName} 으로 변경할 수 있다.
  • checkbox 는 체크되어 있지 않으면 필드 자체가 서버로 전송되지 않아서 NPE 가 발생하거나 기타 문제가 발생할 수 있다. 이런 문제 때문에 Spring MVC 는 submit 시 전송된 name 과 hidden 태그의 _name 을 비교하여 true / false 로 변환해준다.

    1
    2
    3
    
      <input type="checkbox" id="open" name="open"/>
      <input type="hidden" name="_open" value="on"/>
      <!-- checkbox 를 체크하지 않으면 Controller에 null 이 아닌 false가 전달되어 DTO 클래스에 primitive 타입의 필드 선언이 가능하다. -->
    

    하지만 개발자가 일일이 hidden 태그를 작성하는 것은 번거롭기 때문에 checkbox 에 th:field 를 적용하면 타임리프가 자동으로 hidden 태그를 생성해준다.

여러개의 checkbox 를 생성하고 model에 담긴 attribute 객체를 바인드 하는 예제

1
2
3
4
5
6
7
8
@ModelAttribute("regions")
public Map<String, String> regions() {
    Map<String, String> regions = new LinkedHashMap<>();
    regions.put("SEOUL", "서울");
    regions.put("BUSAN", "부산");
    regions.put("JEJU", "제주");
    return regions;
}
1
2
3
4
5
6
<div th:each="region : ${regions}" class="form-check form-check-inline">
    <input type="checkbox" th:field="*{regions}"
            th:value="${region.key}" class="form-check-input">
    <label th:for="${#ids.prev('regions')}"
            th:text="${region.value}" class="form-check-label"></label>
</div>
1
2
3
<input type="checkbox" value="SEOUL" class="form-check-input" id="regions1" name="regions">
<input type="checkbox" value="BUSAN" class="form-check-input" id="regions2" name="regions">
<input type="checkbox" value="JEJU" class="form-check-input" id="regions3" name="regions">
  • Controller 에서 @ModelAttribute 를 함수 레벨에 사용하면 모든 매핑에 함수가 반환하는 객체를 model에 자동으로 추가한다.
  • input 태그와 label 태그를 함께 사용 시 ${#ids.prev()} 혹은 ${#ids.next()} 를 사용해야 한다.
  • Thymeleaf 는 체크박스를 th:each 안에서 사용하면 자동으로 id 속성값 뒤에 숫자를 붙여준다.
This post is licensed under CC BY 4.0 by the author.