Spring MVC - Thymeleaf(1) 기본 기능

Sungjin·2021년 7월 23일
0

Spring

목록 보기
6/23
post-thumbnail

먼저 타임리프를 쓰는 이유 부터

  • 서버 사이드 렌더링을 위해 (Server Side Randering)
    백엔드 서버에서 HTML을 동적응로 렌더링 하는 용도
  • Natural Template
    HTML을 최대한 유지 가능. 웹 브라우저에 동적으로 렌더링 된 HTML 파일을 직접 열어보면 HTML태그들만 존재.
    반면 JSP는 HTML파일을 웹 브라우저에서 열어보면 HTML과 JSP 소스코드들이 막 섞여있는 모습을 볼 수 있음. 이 말은 서버가 존재해야지만 JSP가 랜더링 된다는 뜻.
    타임리프는 동적으로 랜더링 되지 않아도 정적인 HTML 결과를 확인 가능
  • 스프링에서 밀고 있는 기능! 그러니 스프링과의 통합이 잘 되어 있음

요즘 대세는 Thymeleaf!

프론트엔드 개발자가 있는데 배우는 이유??
백엔드 개발자도 admin 페이지 정도는 직접 만들 줄알아야 하기 때문!

핵심 기능 정리

  • 텍스트 - text, utext : 텍스트를 출력하는 기능
    th:text="${data}"
    th:utext="${data}"
    ${} 는 변수 표현식을 의미
    [[$]]는 컨텐츠 안에서 직접 출력

ex)서버에서 data라는 이름의 모델에 문자열"Hello! Thymeleaf"을 담아 보냈다고 가정

<span th:text="${data}">Hello</span>

<span th:utext="${data}">Hello</span>

<span>[[${data}]]</span>

서버 사이드에러 렌더링 되었다면 Hello 대신 Hello! Thymeleaf을 출력하는 것!

utext를 사용하는 이유?
모델에 <원하는 태그>라는 태그를 달고 싶어서 data에 "<태그>Hello! Thymeleaf</태그>" 를 담아서 보내게 되면 <부분은 <로 >부분은 >로 변경될 것 입니다. HTML에서는 <를 태그가 아닌 문자로 표현하기 위해 HTML 엔티티로 변경합니다.
이런 HTML 변경 기능을 이스케이프라고 합니다. 타임리프는 기본적으로 th:text에 이스케이프를 재공합니다.
이를 unescape하기 위해서 utext를 사용하게 됩니다.

  • SpringEL

ex)서버에서 member라는 이름의 모델에 membername이라는 프로퍼티를 가진 객체를 담아 보냈다고 가정

<span th:text="${member.getMembername()}"></span>
<span th:text="${member.membername}"></span>
<span th:utext="${member['membername']}"></span>

<!--memeber가 리스트 였을 때-->
<span th:utext="${member[0].getMembername()}"></span>
<span th:text="${member[0].membername}"></span>
<span th:utext="${member[0]['membername']}"></span>

모든 span태그가 member의 프로퍼티인 membername인 getMembername()을 하신다고 생각하시면 됩니다!

ex)서버에서 member라는 이름의 모델에 membername이라는 프로퍼티를 가진 객체를 담아 보냈다고 가정 - 지역변수 선언
th:with 사용

<!--memeber가 리스트 였을 때-->
<div th:with="first=${member[0]}">
	<span th:utext="${first.membername}"></span>
</div>
  • 기본 객체

${#request} : HttpServletRequest 객체에 접근
${#response} : HttpServletResponse 객체에 접근
${#session} : 현 세션 상황에 대하여 접든
${#servletContext}
${#locale}

파라미터의 접근도 쉽게 하기 위해 param이라는 기능도 제공
${param.data}

  • URL 링크
    @{} 문법 사용

ex)

<a th:href="@{/mvc}">url</a>

<!-- 링크에 파라미터 포함-->
<a th:href="@{/mvc(param1=${param1},param2=${param2})}">url</a>
<a th:href="@{/mvc/{param1}/{param2}(param1=${param1},param2=${param2})}">url</a>
<a th:href="@{/mvc/{param1}(param1=${param1},param2=${param2})}">url</a>
@{/mvc(param1=${param1},param2=${param2})} : /mvc?param1=data1&param2=data2
@{/mvc/{param1}/{param2}(param1=${param1},param2=${param2})} : /mvc/data1/data2
@{/mvc/{param1}(param1=${param1},param2=${param2})} : /mvc/data1?param2=data2
이렇게 해석 됩니다!
  • 리터럴
    리터럴은 소스 코드 상에 고정된 값을 의미
    타임 리프에서는 th:text="'hello'" 이런 식으로 사용.
    공백이 없을 시에는 th:text="hello" '' 생략 가능.
    th:text="hello spring" 이처럼 공백이 있을 때에는 오류. ''(작은 따옴표)로 감싸야함

리터럴 대체
||을 사용
th:text="|hello ${data}|" 이렇게 사용. ${data} 가 변수의 값으로 바뀜.

  • 연산
    자바 연산과 크게 다를 것 없음!

ex)

<!-- 산술-->
<span th:text="10 + 2"></span>
<span th:text="10 % 2 == 0"></span>

<!-- 비교-->
<span th:text="1 gt 10"></span>
<span th:text="1 >= 10"></span>

<!--조건식-->
<span th:text="${data}?: 'no data'"></span>

<!--no operation-->
<span th:text="${data}?: _">no data</span>

나머지는 그냥 자바와 비슷하고 no operation만 눈여겨 봅시다.
no operation이 의미하는 바는 data가 존재하지 않으면 아무 것도 하지 않는 다는 것 입니다. 애초에 타임리프가 없는 것 처럼 동작 하니 "no data"가 그대로 출력 되게 되져

  • 속성값 설정
    ex)
<span class="text" th:attrappend="class='error '"></span>
<span class="text" th:attrappend="class=' error'"></span>
<span class="text" th:classappend="error"></span>

th:attrappend="class='error '" : 뒤 쪽에 공백이 있으므로 class="text error" 이렇게 됩니다.
th:attrappend="class=' error'" : 앞 쪽에 공백이 있으므로 class="error text" 이렇게 됩니다.
이런게 귀찮아서 나온게 th:classappend="error"니다. 바로 class 뒤쪽에 "error"를 더해 줍니다. class="error text"

  • 반복
    th:each 사용
    ex)서버에서 members라는 이름의 모델에 membername과 age라는 프로퍼티를 가진 객체 리스트를 담아 보냈다고 가정
<table >
  <tr>
    <th>이름</th>
    <th>나이</th>
  </tr>
  
  <tr th:each="member:${members}">
    <td th:text="${member.membername}">이름</td>
    <td th:text="${member.age}">나이</td>
</table>
반복에서는 신기한 기능도 있습니다.
th:each="member:${members}" 이 상황에서 th:each="member, 
memberStat:${members}" 처럼 두번 째 파라미터도 가질 수 있습니다.
두번 째 파라미터가 하는 일은 반복 상태에 대하여 보여 줍니다.

ex)

${memberStat.index}
${memberStat.count}
${memberStat.size}
${memberStat.(even이나 odd)}
${memberStat.(first나 last)} 

등등 사용 가능 합니다!

  • 조건 식
    th:if, th:unless(th:if의 반대)
    th:switch, case

ex)

<!-- if, unless-->
th:if="${member.age == 10}"
th:unless="${member.age ge 10}"

<!--switch-->
th:switch="${member.age}"
	th:case="10"
	th:case="20"

이렇게 사용 가능 합니다.

  • 블록
    반복문 같은 것을 사용 시 애매할 때 자주 사용

ex)

<th:block th:each="member:${members}">
  <div>
    <span th:text="${member.membername}"></span>
    <span th:text="${member.age}"></span>
    
  </div>

지금까지 타임리프 기본기능 이었습니다!

이상으로 포스팅을 마치겠습니다. 감사합니다 :)

이 글은 인프런 김영한님의 '스프링 MVC 2편 - 백엔드 웹 개발 핵심 기술'을 수강하고 작성합니다.
출처:https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/dashboard

profile
WEB STUDY & etc.. HELLO!

0개의 댓글