728x90
반응형
thymeleaf 예제
- 간단 예제를 통해 사용법을 익혀본다
- 정리하는데 힘들었다 프론트는 진짜 너무 힘들다.
텍스트 - text, utext
text
- 사용하면 모델에 data 값이 있으면 치환이 일어나게 된다.
<span th:text="${data}"></span>
- [[...]]
- HTML 안에 직접 데이터를 출력 할 수 있다.
- [[${data}]]
예제
Controller
@Controller
@RequestMapping("/basic")
public class BasicController {
@GetMapping("/text-basic")
public String textBasic(Model model) {
model.addAttribute("data", "Hello Spring!");
return "basic/text-basic";
}
}
html
<ul>
<li>th:text 사용 <span th:text="${data}"></span></li>
<li>컨텐츠 안에서 직접 출력하기 = [[${data}]]</li>
</ul>
utext
- 웹브라우저는 < 를 HTML 태그의 시작으로 인식한다.
- 태그의 시작이 아니라 문자로 표현 할 수 있는 방법을 HTML 엔티티라한다.
- th:utext 또는 [(...)]를 사용하자.
예제
- 따라서 th:text 를 사용하면 다음과 같은 예제에서 문제점이 발생한다.
- 화면에는 HTML 태그가 그대로 나온다.
model.addAttribute("data", "Hello <b>Spring!</b>");
SpringEL
- 타임리프에서 변수를 사용할 때는 변수 표현식을 사용한다.
표현식예제
- Controller 에서 보낸 Objec, List, Map 데이터를 다음과 같이 읽을수 있다.
Controller
@GetMapping("/variable")
public String variable(Model model) {
User userA = new User("userA", 10);
User userB = new User("userB", 20);
List<User> list = new ArrayList<>();
list.add(userA);
list.add(userB);
Map<String, User> map = new HashMap<>();
map.put("userA", userA);
map.put("userB", userB);
model.addAttribute("user", userA);
model.addAttribute("users", list);
model.addAttribute("userMap", map);
return "basic/variable";
}
Object
- user.username
- user['username']
- user.getUsername()
<span th:text="${user.username}"></span>
<span th:text="${user['username']}"></span>
<span th:text="${user.getUsername()}"></span>
List
- users[0].username
- list.get(0).getUsername()
- users[0]['username']
<span th:text="${users[0].username}"></span>
<span th:text="${users[0]['username']}"></span>
<span th:text="${users[0].getUsername()}"></span>
Map
- userMap['userA'].username
- userMap['userA']['username']
- userMap['userA'].getUsername()
<span th:text="${userMap['userA'].username}"></span>
<span th:text="${userMap['userA']['username']}"></span>
<span th:text="${userMap['userA'].getUsername()}"></span>
유틸리티 객체와 날짜
- 타임리프는 문자, 숫자, 날짜, URI를 편하게 다루는 유틸을 제공한다.
예제
날짜
Controller
@GetMapping("/date")
public String date(Model model) {
model.addAttribute("localDateTime", LocalDateTime.now());
return "basic/date";
}
<span th:text="${#temporals.format(localDateTime, 'yyyy-MM-dd HH:mm:ss')}"></span>
<span th:text="${#temporals.month(localDateTime)}"></span>
<span th:text="${#temporals.monthName(localDateTime)}"></span>
<span th:text="${#temporals.monthNameShort(localDateTime)}"></span>
<span th:text="${#temporals.year(localDateTime)}"></span>
<span th:text="${#temporals.dayOfWeek(localDateTime)}">
<span th:text="${#temporals.dayOfWeekName(localDateTime)}"></span>
<span th:text="${#temporals.dayOfWeekNameShort(localDateTime)}"></span>
<span th:text="${#temporals.hour(localDateTime)}"></span>
<span th:text="${#temporals.minute(localDateTime)}"></span>
<span th:text="${#temporals.second(localDateTime)}"></span>
<span th:text="${#temporals.nanosecond(localDateTime)}"></span>
URL 링크
- url 을 생성하는 법을 알아 보자
단순한 URL
- @{...} 문법을 사용하여 생성이 가능하다.
controller
GetMapping("/link")
public String link(Model model) {
model.addAttribute("param1", "data1");
model.addAttribute("param2", "data2");
return "basic/link";
}
html
<a th:href="@{/hello}">basic url</a>
<a th:href="@{/hello(param1=${param1}, param2=${param2})}">hello query param</a>
쿼리 파라미터, 경로변수
- URL 링크에 쿼리파라미터 또는 경로변수를 줄 수 있다.
- 쿼리파라미터
@{/hello(param1=${param1}, param2=${param2})} 아래와 같이 변경된다, () 안에 있는 값들이 쿼리 파라미터 변경된다, /hello?param1=data1¶m2=data2
- 경로변수
@{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})} 아래와 같이 변경이 된다. 즉 ${param1}, ${param1} 값이 치환되어 각 파라미터에 들어간다. hello/data1/data2
- 경로변수 + 쿼리 파라미터
@{/hello/{param1}(param1=${param1}, param2=${param2})} 아래와 같이 변경된다 위와 다른 점은 param2 에 대한 값이 없기 때문에 자동으로 쿼리 파라미터로 들어가게 된다. /hello/data1?param2=data2
리터럴 대체
- string 을 thmeleaf 에서 쓰게 되면 다음과 같은 실수를 범한다.
오류발생 코드
- 띄어 쓰기를 하게 되면 인식을 못한다. '' 으로 감싸줘야 한다.
<span th:text="hello world!"></span>
리터럴 대체를 사용하여 편하게 쓰기
- |....| 을 쓰게 되면 알아서 문자로 처리가 된다.
<span th:text="|hello ${data}|">
Javascript Inline
- 자바스크립트에서 thymeleaf 를 쉽게 쓸수 있도록 인라인 기능을 제공해 준다.
<script th:inline="javascript">
예제
controller
@GetMapping("/javascript")
public String javascript(Model model) {
model.addAttribute("user", new User("userA", 10));
addUsers(model);
return "basic/javascript";
}
html
<body>
<!-- 자바스크립트 인라인 사용 전 -->
<script>
var username = [[${user.username}]];
var age = [[${user.age}]];
//자바스크립트 내추럴 템플릿
var username2 = /*[[${user.username}]]*/ "test username";
var user = [[${user}]];
</script>
<!-- 자바스크립트 인라인 사용 후 -->
<script th:inline="javascript">
var username = [[${user.username}]];
var age = [[${user.age}]];
//자바스크립트 내추럴 템플릿
var username2 = /*[[${user.username}]]*/ "test username";
//객체
var user = [[${user}]];
</script>
</body>
결과
- 텍스트 렌더링
- 아래와 같이 text 로 값이 들어가는지 아닌지에 차이가 있다.
- 인라인 사용 전: var username = userA;var username = [[${user.username}]];
- 인라인 사용 후: var username = "userA"; - 자바스크립트 내추럴
- thymeleaf 는 HTML 파일을 직접 열어도 동작하는 내추럴 템플릿 기능을 제공한다.
- 아래와 같이 차이가 발생한다.
- 인라인 사용전에는 그냥 그대로 해석해 버린다.
- 인라인 사용 전 var username2 = /*userA*/ "test username";var username2 = /*[[${user.username}]]*/ "test username"
- 인라인 사용 후 var username2 = "userA"; - 자바스크립트 인라인 each
- 다음과 같은 문법을 쓰면 반복문이 가능한다.
- 결과
<script> var user1 = {"username":"userA","age":10}; var user2 = {"username":"userB","age":20}; var user3 = {"username":"userC","age":30}; </script>
[# th:each="user, stat : ${users}"] var user[[${stat.count}]] = [[${user}]]; [/]
Check Box
- 체크박스의 경우 체크를 하지 않으면 null 값이 넘어오게된다.
- 하지만 thymeleaf를 쓰게되면 이러한 부분이 해결이 된다.
- 그이유는 자동으로 필요한 코드를 생성해준다.
<div>
<div class="form-check">
<input type="checkbox" id="open" th:field="*{open}" class="form-check-input">
<label for="open" class="form-check-label">판매 오픈</label>
</div>
</div>
변경된값.
<div>
<div class="form-check">
<input type="checkbox" id="open" class="form-check-input" name="open" value="true">
<!--자동으로 생성된 코드-->
<input type="hidden" name="_open" value="on"/>
<label for="open" class="form-check-label">판매 오픈</label>
</div>
</div>
Multi Check Box
@ModelAttribute
- 체크박스를 만들기 위해 매번 모델에 데이터를 넣는게 불편하다.
- 해당 어노테이션으로 쉽게 해결이가능하다.
- 하지만 static 으로 선언하는게 효율적이긴하다.
@ModelAttribute("regions")
public Map<String, String> regions() {
Map<String, String> regions = new LinkedHashMap<>(); regions.put("SEOUL", "서울");
regions.put("BUSAN", "부산");
regions.put("JEJU", "제주");
return regions;
}
html
- th:for="${#ids.prev('regions')}"
- 반복문으로 여러개의 체크 박스를 만들때 각각의 id값을 다르게 만들어 주는 역할을 한다.ㅅ
<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>
실제 생성되는 예제
<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">
타임리프 체크확인
- 멀티 체크 박스에서 등록 지역을 선택해서 저장하면, 조회시에 checked 속성이 추가된 것을 확인할 수 있다.
타임리프는 th:field 에 지정한 값과 th:value 의 값을 비교해서 체크를 자동으로 처리해준다.
Radio Button
-
아래 처럼 직접 접근 할 수도 있다.
<div th:each="type : ${T(hello.itemservice.domain.item.ItemType).values()}"> - Enum 값을 이용하여 추가를 해보자.
Enum
public enum ItemType {
BOOK("도서"), FOOD("음식"), ETC("기타");
private final String description;
ItemType(String description) {
this.description = description;
}
public String getDescription()
{
return description;
}
}
ModelAttribute
@ModelAttribute("itemTypes")
public ItemType[] itemTypes() {
return ItemType.values();
}
html
<div th:each="type : ${itemTypes}" class="form-check form-check-inline">
<input type="radio" th:field="*{itemType}" th:value="${type.name()}"
class="form-check-input">
<label th:for="${#ids.prev('itemType')}" th:text="${type.description}" class="form-check-label">
BOOK
</label>
</div>
Select Box
- 셀렉트 박스 만들기
@ModelAttribute("deliveryCodes")
public List<DeliveryCode> deliveryCodes() {
List<DeliveryCode> deliveryCodes = new ArrayList<>();
deliveryCodes.add(new DeliveryCode("FAST", "빠른 배송"));
deliveryCodes.add(new DeliveryCode("NORMAL", "일반 배송"));
deliveryCodes.add(new DeliveryCode("SLOW", "느린 배송"));
return deliveryCodes;
}
html
<!-- SELECT -->
<div>
<div>배송 방식</div>
<select th:field="*{deliveryCode}" class="form-select"> <option value="">==배송 방식 선택==</option>
<option th:each="deliveryCode : ${deliveryCodes}" th:value="${deliveryCode.code}"
th:text="${deliveryCode.displayName}">FAST</option>
</select>
</div>
참고
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/dashboard
728x90
반응형
'Spring > spring mvc 2 스터디' 카테고리의 다른 글
[Spring] Validation: Validator (0) | 2022.02.02 |
---|---|
[Spring] Validation: 오류코드, 메시지 처리 (0) | 2022.02.01 |
[Spring] Validation: BindingResult (0) | 2022.02.01 |
[Spring] thymeleaf 기본 문법 (0) | 2021.12.19 |
[Spring] thymeleaf 개요 (0) | 2021.12.16 |
댓글