[백엔드] 타임리프 기본기능 요약

유승선 ·2022년 10월 27일
0

Spring 강의

목록 보기
8/12
post-thumbnail

타임리프의 여러가지 기능이 있지만 프로젝트를 만들때 꼭 필요한 기능들을 위주로 작성하겠다.

타임리프란?

타임리프란?

서버 사이드 HTML 랜더링 (SSR) 특징이 있다.
백엔드 서버에서 HTML 을 동적으로 렌더링 하는 용도로 사용된다.

네츄럴 템플릿

타임리프는 순수 HTML 을 최대한 유지하는 특징이 있다.
순수 HTML 을 그대로 유지하면서 뷰 템플릿도 사용할 수 있는 타임리프의 특징을 네츄럴 템플릿 이라 한다.

크게 본다면 위와 같이 설명 할수도 있다.


text, utext

일반적인 텍스트 출력 방식이다. th:text = ${data} 형식으로만 기억한다면 텍스트를 저장하고 추가적인 글을 써서 화면에 보이게 할수 있다.


SpringEL

타임리프에서 변수를 사용할 때는 변수 표현식을 사용한다. 위에 th:text 와 비슷한 맹락이지만 쓰임새가 다를 수 있다.

위와 같이 User 오브젝트의 정보를 모델에 담는경우, 리스트를 담는경우, 또 맵을 담는 경우를 확인해보겠다.

출력하는 방법은 위와 같이 쓸 수 있다.

타임리프에 :text 를 활용하면 원하는 정보를 빠르게 출력 가능하다.


반복

반복 기능의 핵심은 th:each = "variable : ${lst}" 형식 같다. 일반적인 프로그래밍 언어에서 for 룹을 돌리는거와 비슷해보였다. 다만 th:each 가 사용된다.


URL 링크

타임리프의 URL 생성 방법은 @{...} 문법을 사용한다.

가장 단순한 URL 생성은 위와 같이 하고 실제 타임리프에서는 이렇게 적는다.

그러나 쿼리 파라미터로 넘겨야 하는경우에는 조금 다르다.

경로를 포함하지 않고 쿼리 파라미터를 넘길때. 경로를 포함해서 넘길때의 경우다.

주로 수정? 같은 기능을 타임리프에서 만들때 사용되는것이 확인된다.


타임리프 스프링 통합

타임리프는 스프링과 굉장히 잘 맞는 궁합이 나오는데 스프링을 사용할때 편리한 기능들을 제공해주기 때문이다.

위와 같은 기능들을 제공해주는데 개인적으로 편리한 폼 관리를 위한 추가 속성이 개발자로서 타임리프를 선택하게 해주는거 같다.


입력 폼 처리

신기하다고 생각했던 부분이었다. th:object{} 로 변수를 지정해준다음에 th:field 를 사용해서 객체의 필드를 직접 접근 할 수 있다.

과정

@GetMapping("/add")
public String addForm(Model model) {
 model.addAttribute("item", new Item());

이렇게 모델을 넘긴 후에

타임리프에서 이렇게 작성해준다면,

굳이 item.itemName 이 아니더라도 바로 위에 ${item}으로 오브젝트를 잡아주었기에 자동으로 인식이 되서 사용 가능하다. 이외에 내가 조금 헷갈렸던건 "label for = "itemName"" 이었는데 입력폼에서 데이터를 넣으면은 itemName 으로 데이터가 넣어지는것을 알았다.


체크 박스, 라디오 버튼, 셀렉트 박스

체크 박스

어떤 상품을 등록을 할때 체크 박스를 사용해서 위와 같은 상황을 만드는 시나리오다.

package hello.itemservice.domain.item;
public enum ItemType {
 BOOK("도서"), FOOD("식품"), ETC("기타");
 private final String description;
 ItemType(String description) {
 this.description = description;
 }
 public String getDescription() {
 return description;
 }
}

ItemType 을 이렇게 만들고

package hello.itemservice.domain.item;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
 * FAST: 빠른 배송
 * NORMAL: 일반 배송
 * SLOW: 느린 배송
 */
@Data
@AllArgsConstructor
public class DeliveryCode {
 private String code;
 private String displayName;
}

배송 방식의 코드도 만들어 주었다.

package hello.itemservice.domain.item;
import lombok.Data;
import java.util.List;
@Data
public class Item {
 private Long id;
 private String itemName;
 private Integer price;
 private Integer quantity;
 private Boolean open; //판매 여부
 private List<String> regions; //등록 지역
 private ItemType itemType; //상품 종류
 private String deliveryCode; //배송 방식
 public Item() {
 }
 public Item(String itemName, Integer price, Integer quantity) {
 this.itemName = itemName;
 this.price = price;
 this.quantity = quantity;
 }
}

가장 핵심인 Item 클래스 안에서 체크박스를 이용하여 판매 여부를 확인해주는게 첫번째 과제다.

글의 길이가 길어질까봐 생략하지만 단일박스를 만드는 첫번째 방법같은 경우 순수 HTML 로 만들게 되면 체크박스에 체크를 안해주었을때 null 값이 보내진다는 불편함이 있다. 그래서 타임리프를 이용한 체크박스를 사용하게 되는데,

이렇게 하면 null 값이 아니고 빈값으로 보낼경우 false 로 반환된다. 순수하게 html로 타임리프의 코드를 열어보면

앞서 설명한 히든 필드까지 전부 나오는것을 볼 수 있다.


체크박스 멀티

체크박스를 이용한 선택지에서 단일 체크를 확인해봤으니 멀티 체크박스를 선택하는것도 가능하다.

멀티 체크박스란 하나의 선택지만 두는것이 아니고 여러가지 선택지를 클릭해서 여러개의 값이 들어가는것을 뜻한다. 그리고 Items 클래스를 보면은 Regions 라는 List 가 있는데 여기에다가 선택된 지역들을 전부 넣는것이다.

@ModelAttribute("regions")
public Map<String, String> regions() {
 Map<String, String> regions = new LinkedHashMap<>();
 regions.put("SEOUL", "서울");
 regions.put("BUSAN", "부산");
 regions.put("JEJU", "제주");
 return regions;
}

새로운 형식의 @ModelAttribute 어노테이션 활용법이다. 이 부분은 지역을 regions 라는 모델로 글로벌하게 넣기 위한 방법으로 사용되었다.

가장 중요하다고 생각했던 체크박스 부분. 먼저 맵을 읽어주면서 items.regions 에 값을 넣어주었다. 여기서 특이점은 {...} 부분을 th:for 위에 넣어주었다는 점, 그리고 th:for 에 #ids.prev 라는 새로운 표현을 넣어준것이다

th:for 은 html에서는 id로 해석할 수 있는데 이 아이디에 따라서 th:field 에 값이 넣어지는것이다. 그런데 여러개의 선택지면은 당연히 서울에 필요한 id 값, 부산에 필요한 id 값이 달라져야하기 때문에 #ids.prev 를 넣으면 임의로 1,2,3 숫자각 더해진다.

실제 HTML 을 까보면 위와 같이 나온다.

로그 출력을 하면은 리스트 형식으로 값이 깔끔하게 들어간것을 확인 가능하다.


라디오 버튼

체크박스와는 다르게 라디오 버튼은 여러가지 선택지 중에 하나를 선택할 수 있다. 그리고 무조건 적으로 하나의 선택지를 가져와야 하는 특징이 있다.

위에서 만들었던 ItemType을 기준으로 Radio 버튼을 활성화 시킬것이다.

결국 itemTypes 안에 있는 타입 정보를 바탕으로 th:each 를 돌려야 하기때문에 이렇게 ModelAttribute 를 만들어준다면은 배열로 반환이 된다.

혹시라도 헷갈릴 수 있지만 th:each 에서 사용된 itemTypes 는 위에 ModelAttribute 로 만든 아이템 모델이고 th:field에서 사용된 itemType은

package hello.itemservice.domain.item;
import lombok.Data;
import java.util.List;
@Data
public class Item {
 private Long id;
 private String itemName;
 private Integer price;
 private Integer quantity;
 private Boolean open; //판매 여부
 private List<String> regions; //등록 지역
 private ItemType itemType; //상품 종류
 private String deliveryCode; //배송 방식
 public Item() {
 }
 public Item(String itemName, Integer price, Integer quantity) {
 this.itemName = itemName;
 this.price = price;
 this.quantity = quantity;
 }
}

여기서 필드값으로 만든 itemType이다. 라디오로 선택된 값을 itemType에 넣는다고 생각하면 좋을거같다. 그리고 th:value 로 넣어지는 인풋은 itemTypes 안에 있는 Food, Book 이렇게 넣어질것이다. 추가적으로 th:for 로 생성되는 id값은 regions 에제에서 나왔듯이 임의로 1,2,3 값을 아이디에 붙힐서이고 th:text에 type.description 을 넣은것으로 Food로 나오는게 아니고 "음식", "도서" 이렇게 선택을 할 수 있다.

로그 정보 결과다.


셀렉트 박스

셀렉트 박스 또한 여러가지 선택지 중에서 하나를 선택할 수 있다.

이렇게 나오는게 셀렉트 박스의 예시고 이번에는 enum 클래스가 아니고 일반적인 자바 객체를 사용해볼 수 있다.

package hello.itemservice.domain.item;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
 * FAST: 빠른 배송
 * NORMAL: 일반 배송
 * SLOW: 느린 배송
 */
@Data
@AllArgsConstructor
public class DeliveryCode {
 private String code;
 private String displayName;
}

DeliveryCode 를 위한 자바 객체이다.

package hello.itemservice.domain.item;
import lombok.Data;
import java.util.List;
@Data
public class Item {
 private Long id;
 private String itemName;
 private Integer price;
 private Integer quantity;
 private Boolean open; //판매 여부
 private List<String> regions; //등록 지역
 private ItemType itemType; //상품 종류
 private String deliveryCode; //배송 방식
 public Item() {
 }
 public Item(String itemName, Integer price, Integer quantity) {
 this.itemName = itemName;
 this.price = price;
 this.quantity = quantity;
 }
}

이번엔 Item 필드에 deliveryCode 로 값을 설정할것이다.

똑같이 ModelAttribute 특성을 써서 deliveryCodes 모델을 만들어주었고 여기에 List 안에는 각 DeliveryCode 객체들을 넣어주었다.

타임리프로 만들어진 코드고 비슷하지만 다른 방식으로 셀렉트 박스를 위해서 select 를 넣어주었고 th:field 로는 deliveryCode 를 선택해주었다. 위에서 설명한 Radio와 비슷하게 th:each 로 ${deliveryCodes} 리스트를 루프 돌리면서 th:text로 보여지는 텍스트와 th:field 에 값으로 넣어줄 th:value 또한 지정해주었다.

HTML 버전으로 나오게 되면 위와 같은 방법으로 나오게된다.


참고

김영한의 Spring MVC 2편 - 타임리프

profile
성장하는 사람

0개의 댓글