본문 바로가기
Spring Boot (프로젝트)

Thymeleaf 정리 (JSP와 차이)

by Hoozy 2023. 3. 8.

대분류 : 타임리프

템플릿 엔진

  • 템플릿 양식과 특정 데이터 모델에 따른 입력 자료를 합성하여 결과 문서를 출력하는 소프트웨어 또는 소프트웨어 컴포넌트.
  • 지정된 템플릿 양식과 데이터가 합쳐져서 HTML 문서를 출력하는 소프트웨어
  • 사용하는 이유
    1. 많은 코드를 줄일 수 있다.
    2. 재사용성이 높다.
    3. 유지보수에 용이하다.

서버 사이드 템플릿 엔진

  • 서버에서 DB 혹은 API에서 가져온 데이터를 미리 정의된 템플릿에 넣어 HTML 문서를 만들어 클라이언트에 전달해주는 역할을 한다.
  • HTML 코드에서 고정적으로 사용되는 부분은 템플릿으로 만들어두고 동적으로 생성되는 부분만 템플릿의 특정 부분에 끼워 넣는 방식으로 동작한다.
  • EX) JSP, Thymeleaf, Velocity, Freemarker

클라이언트 사이드 템플릿 엔진

  • HTML 형태로 코드를 작성할 수 있으며, 동적으로 DOM을 그리게 해주는 역할을 한다.
    • DOM(Document Object Model) : 웹 브라우저가 HTML 페이지를 인식하는 방식.
  • EX) Mustache, Squirrelly

JSP

  • 자바 언어를 기반으로 하는 서버 사이트 스크립트 언어.
  • HTML 코드에 JAVA 코드를 넣어 동적인 웹 페이지를 생성할 수 있다.
  • WAS에 의해 서블릿 클래스로 변환되어 사용된다.
  • JAVA 코드에 HTML 코드를 넣는 SERVLET과 비슷하지만 다르다.

Thymeleaf

  • 스프링부트에서 공식적으로 지원하고 권장하는 템플릿 엔진.
  • JSP보다 성능과 기능면에서 우세하다.
  • HTML5용 자바 템플릿 엔진
  • 웹 및 오프라인 환경 모두에서 작동 가능하다.
  • 서블릿 API에 대한 하드 종속성 없음
  • 방언 혹은 사투리 기능이라 불리는 모듈형 형상 집합에 기초한다.
  • 전체 국제화를 지원한다.

Thymeleaf 문법

  • GRADLE에 dependency
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' 추가

1) 설정

xmlns:th=" "

<html lang="en" xmlns:th="http://www.thymeleaf.org">
  • 타임리프의 th속성을 사용하기 위해 선언된 네임스테이스이다.
  • 순수 HTML로만 이루어진 페이지인 경우 선언하지 않아도 된다.

2) 기본 기능

th:text="${}"

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

JSP의 EL 표현식인 ${}와 마찬가지로 ${} 표현식을 사용해서 컨트롤러에서 전달받은 데이터에 접근할 수 있다.

th:href="@{}"

<body>
  <a th:href="@{/boardListPage?currentPageNum={page}}"></a>
</body>
  • <a> 태그의 href 속성과 동일.
  • 괄호안에 클릭시 이동하고자하는 url을 입력하면 된다.

th:with="${}"

<div th:with=”userId=${number}” th:text=”${usesrId}”>
  • 변수형태의 값을 재정의 하는 속성이다.
  • th:with를 이용하여 새로운 변수값을 생성할 수 있다.

th:value="${}"

<input type="text" id="userId" th:value="${userId} + '의 이름은 ${userName}"/>
  • inpit의 value에 값을 삽입할 때 사용한다.
  • 여러개의 값을 넣을땐 + 기호를 사용한다.

3) Layout

xmlns:layout="", layout:decorator=""

<html lang="ko" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{board/layout/basic}">
  • Gradle
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
  • 타임리프의 layout 기능을 사용하기 위해서 의존성을 추가해야 한다.
  • xmlns:layout은 타임리프의 레이아웃 기능을 사용하기 위한 선언이다. 레이아웃을 적용시킬 HTML파일에 해당 선언을 한다. 그리고 해당 페이지에 th:fragment로 조각한 공통 영역을 가져와서 삽입한다.

th:block

<html lagn="ko" 
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<body>
      //전체 레이아웃
    <th:block th:fragment="footerFragment">
     </th:block>
</body>  

</html>
  • block은 타임리프 표현을 어느 곳에서든 사용할 수 있도록 하는 구문이다.
  • 해당 기능은 동적인 처리가 필요할 때 사용된다. 주로 layout 기능이나 switch에 사용이 많이 된다.

th:fragment=""

<body>

<footer th:fragment="footerFragment">
  <p>안녕하세요</p>
</footer>

</body>
  • 웹 페이지에 메뉴 탭이나 네비게이션바와 같이 공통으로 반복되는 영역이 존재한다. 이 공통의 영역들을 매 페이지마다 HTML코드를 반복해서 쓰면 지저분 하여 fragment가 바로 공통 영역을 정의하여 코드를 정리해준다.
  • 특히, header, footer에 삽입하여 조각화 한다. 이렇게 만들어진 조각을 삽입하고자 하는 대상 HTML 파일에서 th:replace"파일경로 :: 조각 이름"을 통해 삽입한다.

th:replace="~{파일경로 :: 조각이름}"

<body>
  <div th:replace="~{/common/footer :: footerFragment}"></div>  
</body>
  • JSP의 <include> 태그와 유사하다.
  • fragment로 조각화한 공통 영역을 HTML에 삽입하는 역할을 한다.
  • :: 을 기준으로 앞에는 조각이 있는 경로를 뒤에는 조각의 이름을 넣어준다.
  • insert와 다르게 완전하게 대체한다.

th:insert="!{파일경로 :: 조각이름}"

<body>
  <div th:insert="~{/common/footer :: footerFragment}"></div>  
</body>
  • insert는 태그 내로 조각을 삽입하는 방법이다. replace는 완전하게 대체하기 때문에 replace 태그가 입력된 <div>가 사라지고 fragment로 조각화한 코드가 완전히 대체된다.
  • 하지만 insertinsert가 입력된 <div>안에 fragment를 삽입하는 개념이기 때문에 <div>안에 조각화 한 코드가 삽입된다.
  • 형식은 replace와 동일.

4) Form

<body>
  <form th:action="@{/join}" th:object="${joinForm}" method="post">
    <input type="text" id="userId" th:field="*{userId}" >
    <input type="password" id="userPw" th:field="*{userPw}" >
  </form>
</body>

th:action="@{}"

  • <form>태그 사용시, 해당 경로로 요청을 보낼 때 사용한다.

th:object="${}"

  • <form>태그에서 데이터를 보내기 위해 submit을 할 때 데이터가 th:object 속성을 통해 object에 지정한 객체에 값을 담아 넘긴다. 이때 값을 th:field 속성과 함께 사용하여 넘긴다.
  • Controller와 View 사이의 DTO클래스 객체라고 생각하면 된다.

th:field="*{}"

  • th:object 속성과 함께 th:field 를 이용해서 HTML 태그에 멤버 변수를 매핑할 수 있다.
  • th:field 를 이용한 사용자 입력 필드는 id, name, value 속성 값이 자동으로 매핑된다.
  • th;object와 th:field는 Controller에서 특정 클래스의 객체를 전달 받은 경우에만 사용.

5) 조건문과 반복문

th:if="${}", th:unless="${}

<span th:if="${userNum} == 1"></span> 
<span th:unless="${userNum} == 2"></span>
  • JAVA의 조건문에 해당하는 속성이다. 각각 if 문, else 문이다.
  • th:unless는 일반적인 언어의 else 문과는 달리 th:if에 들어가는 조건과 동일한 조건을 지정해야 한다.
    • 같은 조건이어야 아닐 때의 조건이 되기 때문에

th:each="변수 : ${list}"

<body>
  <li th:each="pageButton" : ${#numbers.sequece(paging.firstPage, paging.lastPage)}></li>
</body>
  • JSP의 JSTL에서 <c:foreach> 그리고 JAVA의 반복문 중 for 문을 뜻한다.
  • ${list}로 값을 받아온 것을 변수로 하나씩 가져온다는 뜻으로, 변수는 이름을 맘대로 지정할 수 있다.

th:switch, th:case

<th:block th:switch="${userNum}"> 
  <span th:case="1">권한1</span> 
  <span th:case="2">권한2</span> 
</th:block>
  • JAVA의 switch-case 문과 동일하다.

6) ETC

numbers.sequest(start, end, step)

  • 기본적으로 타임리프에서는 #numbers 라는 숫자 포맷 메소드를 지원한다. #numbers 에는 다양한 메소드들이 존재하는데 가장 많이 사용하는 것이 #numbers.sequence이다.
  • #numbers.sequence 메소드는 start, end, step을 이용하여 원하는 범위에 대해 시퀀스를 생성해준다.

#strings

  • 많이 쓰는 4가지가 있고,

  • equals : ${#strings.equlas(str, 'equal')} 문자열 str 이 'equal'과 같으면 true, 아니면 false

  • setSplit : ${#strings.setSplit(str, '/')} 문자열 str 을 '/' 기준으로 나누어서 문자열 배열로 반환

  • replace : ${#strings.replace(str, 'aaa')} 문자열 str 을 'aaa'로 바꾸기

  • contains : ${#strings.contains(str, 'a')} 문자열 str 이 'a' 를 포함하면 true, 아니면 false

  • 아래에 자세하게 설명되어 있습니다.
    https://hajoung56.tistory.com/72

참고 자료
https://velog.io/@alicesykim95/Thymeleaf

댓글