타임리프에서는 form 태그
를 효율적으로 사용할 수 있도록 도와주는 기능이 내장되어 있다. 이를 활용하기 위해서는 컨트롤러에서 모델로 객체를 넘겨주어 이를 받아서 활용할 수가 있는데 이때 이 객체를 th:object
를 이용해 활용할 수 있다.
form에 어떤 객체의 내용을 넣을 때, "${...}"
문법을 활용했는데, th:object
를 활용하여 어떻게 바뀌는지 기능을 알아보자.
th:object
를 이용해 컨트롤러로 부터 받은 객체를 지정한다. 이때, model.attribute로 지정한 이름과 동일해야 한다.
form 태그 내에서 이 객체에 접근할 때는 기존과 같이 ${item.name}
과 같은 방식으로 접근할 수 있지만, th:object
를 손쉽게 활용할 수 있도록 타임리프에서 문법을 제공한다. *{...}"
이를 활용하면 "${item.name}"
== "*{name}"
완전히 동일한 기능이다. item이 생략될 수 있는 것은 th:object
에서 이미 객체가 지정되었기 때문.
th:field
를 이용한 간편한 기능 제공
th:object
와 함께 th:field
기능을 제공하는데 이는 아래와 같이 이용할 수 있다. th:field = "*{name}"
이렇게 사용하게 되면 input 태그에 "*{name}"
과 동일한 이름으로 id, name, value 세 가지 속성을 자동으로 만들어준다.
<form action="item.html" th:action method="post">
<div>
<label for="id">상품 ID</label>
<input type="text" id="id" name="id" class="form-control" value="1" th:value="${item.id}" readonly>
</div>
<div>
<label for="itemName">상품명</label>
<input type="text" id="itemName" name="itemName" class="form-control" value="상품A" th:value="${item.itemName}">
</div>
<div>
<label for="price">가격</label>
<input type="text" id="price" name="price" class="form-control" value="10000" th:value="${item.price}">
</div>
<div>
<label for="quantity">수량</label>
<input type="text" id="quantity" name="quantity" class="form-control" value="10" th:value="${item.quantity}">
</div>
<!-- 코드 생략 -->
</form>
<form action="item.html" th:action th:object="${item}" method="post">
<div>
<label for="id">상품 ID</label>
<input type="text" th:field="*{id}" class="form-control" value="1" readonly>
</div>
<div>
<label for="itemName">상품명</label>
<input type="text" th:field="*{itemName}" class="form-control" value="상품A" >
</div>
<div>
<label for="price">가격</label>
<input type="text" th:field="*{price}" class="form-control" value="10000">
</div>
<div>
<label for="quantity">수량</label>
<input type="text" name="quantity" class="form-control" value="10" th:field="*{quantity}">
</div>
<!-- 코드 생략 -->
</form>
id, name, value가 자동으로 들어가게 되었고, id와 name은 th:field = "*{...}"
의 이름과 동일하게 생성되었다.
위의 케이스는 보통 객체를 넘겨서 값을 수정하는 수정폼의 경우에 많이 사용되는 경우이다. 하지만 객체를 처음 생성하는 경우에도 model에 빈 객체를 담아서 보내게 되면 컴파일러가 이를 체크해준다.
김영한 님의 말에 따르면 객체 하나는 새로 만드는 것은 큰 비용이 들지 않는다고 한다. 따라서 이런 기능을 활용하는 것이 개발자로서 에러를 잡는데 더욱 도움을 준다.
<form action="item.html" th:action th:object="${item}" method="post">
<div>
<label for="id">상품 ID</label>
<input type="text" th:field="*{id}" class="form-control" value="1" readonly>
</div>
<div>
<label for="itemName">상품명</label>
<input type="text" th:field="*{itemName}" class="form-control" value="상품A" >
</div>
<div>
<label for="pric">가격</label>
<input type="text" th:field="*{price}" class="form-control" value="10000">
</div>
<div>
<label for="quantity">수량</label>
<input type="text" name="quantity" class="form-control" value="10" th:field="*{quality}">
</div>
<!-- 코드 생략 -->
</form>
위 코드를 보면 현재 수량 부분에 th:field="*{quality}"
라고 일부러 오타를 냈다. 이런 경우에 컴파일러가 객체를 체크해서 없는 필드인 경우에는 에러를 잡아준다.
따라서 이와 같은 기능을 통해 에러를 쉽게 찾을 수 있도록, 폼을 등록할 때에도 빈 객체를 전달해주면 좋다!