Free Lines Arrow
본문 바로가기
Spring/spring mvc 2 스터디

[Spring] thymeleaf 예제

by skahn1215 2022. 1. 6.
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를 편하게 다루는 유틸을 제공한다.

예제

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#appendix-b-expression-utility-objects

 

Tutorial: Using Thymeleaf

1 Introducing Thymeleaf 1.1 What is Thymeleaf? Thymeleaf is a modern server-side Java template engine for both web and standalone environments, capable of processing HTML, XML, JavaScript, CSS and even plain text. The main goal of Thymeleaf is to provide a

www.thymeleaf.org

 

날짜

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&param2=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 = [[${user.username}]];
     - 인라인 사용 전: var username = userA;
    - 인라인 사용 후: var username = "userA";

  • 자바스크립트 내추럴
    - thymeleaf 는 HTML 파일을 직접 열어도 동작하는 내추럴 템플릿 기능을 제공한다.
    - 아래와 같이 차이가 발생한다.
    - 인라인 사용전에는 그냥 그대로 해석해 버린다.
    var username2 = /*[[${user.username}]]*/ "test username"​
    - 인라인 사용 전 var username2 = /*userA*/ "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

 

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 인프런 | 강의

웹 애플리케이션 개발에 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. MVC 2편에서는 MVC 1편의 핵심 원리와 구조 위에 실무 웹 개발에 필요한 모든 활용 기술들을 학습할 수 있

www.inflearn.com

 

728x90
반응형

댓글