본문 바로가기
공부/java

타임리프 사용법

by 샤샤샤샤 2023. 1. 22.

StaticWeb(정적 웹페이지)

static폴더에 html파일을 만들어야 한다

안의 데이터가 입력값이나 다른 요인에 따라 동적으로 변하지 않는 정적인 웹페이지를 말한다.

**스프링부트는 따로 맵핑해주지 않아도 초기 값으로 index.html을 초기 페이지로 감지한다. 이는 templates폴더에 있건, resources폴더에 바로 넣건 알아서 찾아진다.

**맵핑(mapping) : 미리 url을 지정해두고, 사용자로부터 어떤 요청이 왔을때 자동적으로 해당 url로 가도록 설정하는 것.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>메인페이지</title>
</head>
<body>
    <h2>스프링부트에 오신 것을 환영합니다.</h2>
    <img src="/img/image1.jpg" style="widht:300px; height:200px;"> <br>
    <a href="/subpage/subpage.html">서브페이지로 이동</a> <br>
    
    파일 다운로드 링크(png,jpg,pdf,zip)
    <a href="https://cdn.discordapp.com/attachments/1022816856077246465/1064782847698796584/image1.jpg"
    download="카페이미지">이미지파일 다운로드 링크</a>

</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>서브페이지</title>
</head>
<body>
  <h2>서브페이지 입니다.</h2>

</body>
</html>
package com.study.springboot;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MainController {
    //URI : localhost:8080/
    @GetMapping("/")
    //@ResponseBody : return 값의 문자열을 응답된 url의 body태그에 끼워넣는다.
    public String main() {
        return "index.html"; //index.html을 응답으로 내려준다.
    }
}

"/"는 현재 위치를 말한다. 따라서 처음 localhost:8080 들어가자마자의 상태를 말하는 셈이다.

따라서 localhost:8080에 접속한 순간, index.html로 이동한다.

이 html폴더 내부의 어떤 데이터도 동적이지 않다. 이런 정적 페이지들을 static폴더에 넣어야 한다.

위의 url을 보면 변하지 않은 것을 알 수 있다. 페이지 이동에는 redirect와 foward방식 두개가 존재하는데, 따로 맵핑하지 않는 이상 기본적으로 foward 방식으로 구동되기 때문이다.

 

redirect : 내부 변수값을 버리고 다른 페이지로 이동. (주로 다른 서버 (도메인)으로 이동할때 사용). url이 변함.

foward: 내부 변수값을 가지고 페이지 이동. (주로 같은 서버 내에서 이동). url이 안변함.

 

 

Thymeleaf (타임리프)

뷰 템플릿 엔진(View Template Engine)이다. html만 열리면 정적인 페이지만 만들수 있을뿐, 동적인 페이지는 만들수 없다. 따라서 서버로부터 받아온 데이터로 html파일을 조작해주는 도구가 필요한데, 그것이 바로 타임리프다.

HTML 최종 결과를 서버에서 만들어 웹 브라우저에 전달하기 위한 엔진이다. html의 순수성을 해치지 않는다는 특징 덕분에 서버를 거치지 않고 파일을 직접 열수도 있으나, 그럴 경우 서버를 거쳐야하는 동적인 데이터들, 화면들은 작동하지 않는다.(JS를 통해 구현된 동적인 동작은 작동한다.)

 

**뷰 템플릿 엔진(View Template Engine). 미리 만들어진 틀(템플릿)안에 데이타를 합성해서 HTML 문서를 만들어내는 소프트웨어를 말한다.

먼저 application.property에서 캐쉬를 저장하지 않도록 설정하자.

spring.thymeleaf.cache=false

한번 html파일을 열면 캐쉬가 저장되며, html이 바뀌지 않았으면 저장된 값으로 불러온다. 그러면 개발자가 개발 과정에서 코드를 바꾸더라도 바뀐 값이 응답으로 내려와지지 않기 때문에 개발자 의도와 다른 값이 출력될수도 있다.

 

사용하기전 반드시 html파일 내에서 Thymeleaf를 가져와야 한다.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>index6.html</title>
</head>
<body>

</body>
</html>

타임리프는 자기만의 독특한 문법이 존재한다. 이를 모두 외울 필요는 없고, 기본적인 것만 기억하고 나머지는 필요할때 찾아 쓰자.

 

사용 방법

1. 타임리프를 스프링부트 프로젝트에 불러온다.(start.spring.io 사용)

2. 개발하는 웹사이트 html파일에도 불러온다.

<html xmlns:th="http://www.thymeleaf.org">

3. 사용하길 원하는 태그 내부에 인라인으로 th: 를 적는다.

 <p th:></p>

4. 원하는 예약어를 적는다.

예)

th:text : innerText로 출력<br>
<p th:text="뇸뇸뇸">InnerText로 출력</p>

th:utext : innerHTML로 출력<br>
<p th:utext="얌얌얌">innerHTML로 출력</p>

5. 서버로부터 변수를 받아 사용하고 싶으면 쌍따옴표(" ") 안에 ${ '변수명' } 을 적어 넣는다.

    <p th:text="${ name_text }">InnerText로 출력</p>

이때, 쌍따옴표로 둘러쌓인 부분이 태그 내부의 값을 대체한다. 따라서 파일이 실행되면 "InnerText로 출력"이라는 문구는 삭제되며, 대신 th:text 내부의 값이 들어가게 된다.

<!--서버의 name값이 홍길동이라고 가정하면 -->

<p> 홍길동 </p> <!-- InnerText로 출력 -- 문구 삭제 -->

<!-- 이 된다 -->

이상이 기본적인 사용법이다.

 

타임리프 표현식

${ '변수명' } : 서버로부터 받은 데이터를 사용하기 위한 타임리프 문법. 동적으로 변하는 데이터를 다룰때 자주 쓰인다.

*{ '변수명' } : 선택된 객체의 필드에 접근할때 사용됨. 먼저 object예약어를 통해 객체를 선택해야 함.

@{ 'html파일명' } : html파일의 경로를 지정해준다. a태그 등에서 th:href 예약어와 같이 쓰인다.

 ' 문자열 ' : 문자열(리터럴)은 띄어쓰기가 포함되어 있다면 반드시 작은 따옴표로 감싸서 사용해야 한다. 덧셈(+) 을 통해 문자열을 이을수도 있다. 변수 사용이 가능하다.

|문자열| : 리터럴 대체 문법. ' ' 대신 |로 문자열을 감싸면 +를 사용하지 않고도 문자열을 이을수 있다. 변수 사용이 가능하다. 

? : 삼항연산자처럼 쓰이나, 조건은 null인가, null이 아닌가 밖에 판별하지 못하며, 참일때 값을 넣으면 오류가 발생한다. 오직 거짓일때 값만 넣을 수 있으며, 값이 null이면 원래값이 출력된다.

    <p th:text="${ address_null } ?: 'address_null은 null입니다.'">삼항연산자 결과</p>

# : ${ #함수명 }처럼 사용한다. 함수 호출전, 함수라는 것을 알리기 위한 예약어. 

 

 

타임리프의 예약어

모든 예약어는 th:'이름' 과 같은 형식으로 쓰며, th는 타임리프가 적용되도록 하는 역할을 한다.

text : 태그에 텍스트 삽입

utext : html을 형태로 텍스트에 삽입

object : 객체를 선택한다.

block: 태그를 여는 곳과, 닫는 곳, 두군데 모두 쓴다. block은 타임리프 표현을 어느 곳에서든 사용할 수 있도록 하는 구문이다. 해당 기능은 동적인 처리가 필요할 때 사용된다. 주로 layout기능이나 switch에 사용이 많이 된다.

not : 부정 예약어. boolean값을 반전시킨다.

if : 조건문.

unless : 거짓일때 조건문. 타임리프는 else표현이 존재하지 않아 조건이 거짓인 조건식을 쓰고 싶으면 unless나 !=를 사용해야 한다.

switch : 기존 언어들의 switch - case문의 역할을 한다. 상위 태그에 th:switch = ${ '변수명' } 과 같은 식으로 작성한 뒤, 하위 태그에 th:case = '변수의 경우들' 과 같은 식으로 작성한다. 변수가 케이스 조건에 참인 태그만 구현된다.

  <div th:switch="${ role }">
    <p th:case="'admin'"> 사용자는 관리자입니다. </p>
    <p th:case="'guest'"> 사용자는 손님입니다. </p>
    <p th:case="'*'"> 사용자는 그 외 권한입니다. </p>
  </div>

each : 타임리프의 반복문. 

each는 자바의 향상된 for문(for each문)의 문법 일부와, 반복상태를 추적할수 있는 status 변수를 제공한다.

기본적인 사용법

    <p th:each=" a, status:${ list }" th:text="${a.user_name}"></p>

list라는 이름으로 받은 데이터는 List<Member>타입의 데이터로, 3개의 인덱스를 가지고 있으며 내부에 user_name값을 가지고 있다. 직접 코드를 쓰기에는 큰 의미도 없는 코드들이 너무 방대하게 늘어놓는 것 같아서 생략하겠다.

아무튼, 이때 p태그는 3번 생성되며 user_name값을 출력한다.

th: a : ${ list }

이 코드는 list를 순환시켜 얻어오는 내용물, 즉, Member객체를, a라는 임시 변수에 할당하겠다는 의미다.

for(int i=0; i<5; i++){
     list[ i ].id 
}
          
each=" a : ${ list }"
       a.id

 만약 타임리프에 다른 언어들처럼 현재 순환되고 있는 인덱스를 표현할 변수가 존재한다면 list[ i ].id 처럼 표현하면 되겠지만, 안타깝게도 그런 기능이 없으니 따로 변수에 현제 값을 할당하는 것이다.

 

status사용

앞서 말했듯 타임리프의 each문은 다른 언어들처럼 숫를 직접 지정해주거나 변수를 만들어 순환을 돌리지 못하기에, 사용자 입장에서 매우 불편하다. 이러한 불편함을 해결하기 위해 status라는 반복상태변수를 제공한다.

status.index : 현재 반복 인덱스 (0부터 시작합니다.)
status.count : 현재 반복 인덱스 (1부터 시작합니다.)
status.size : 총 요소 수
status.current : 현재 요소
status.even : 현재 반복이 짝수인지 여부 (boolean값)
status.odd : 현재 반복이 홀수인지 여부 (boolean값)
status.first : 현재 반복이 첫번째인지 여부 (boolean값)
status.last : 현재 반복이 마지막인지 여부 (boolean값)

아래와 같이 사용할수 있다.

    <p th:each="a : ${ list }" th:text="${ a.id }"></p>

이름 옆에 순서대로 숫자가 붙은것을 볼 수 있다. 

헌데 여기서 list의 각 인덱스 요소를 잠시 보관하는 a가 이전과 다르게 쓰였다. 이는 status와 임시변수를 동시에 사용할때 지켜야할 타임리프의 규칙이다.

 

타임리프 함수

defaultString( 변수, '문자열') : 함수다. 매개변수로 받은 첫번째 값이 null이라면, default로 설정된 문자열을 반환한다.

isEmpty( 변수 ) : 변수가 null값인지 아닌지 판별하기 위한 함수

 

타임리프의 숫자와 날짜 표현

dates.format( 날짜변수, 심볼) : 날짜 변수를 타임리프에서 표현하기 위해 알맞게 변환시켜주는 함수다.

    <p th:text="${ #dates.format( standardDate, 'yyyy/MM/dd HH:mm:ss') }"></p>
    <!-- standardDate는 미리 controller클래스에서 만들어둔 날짜형 변수다. -->

아래와 같이 사용할수 있으며, 심볼은 날짜만 지정하거나, 시간만 지정하거나, 아예 지정하지 않을수도 있다.

 

numbers.formatInteger ( 숫자, 끊을 단위, 사이에 삽입되는 문자) : 숫자를 3개씩 끊어서 중간중간 쉼표( , )를 넣거나 할때             사용하는 함수다. 첫번째 매개변수에 원래 숫자, 두번째 매개변수에 끊을 단위( 2을 적으면 2개씩 끊김), 끊긴 숫자               사이에 넣고 싶은 문자를 미리 지정된 예약어로 넣는다.

         'POINT', 'COMMA', 'WHITESPACE', 'NONE', 'DEFAULT' 가 존재한다.

예약어: 'POINT', 'COMMA', 'WHITESPACE', 'NONE', 'DEFAULT'
출력값:   .         ,       띄어쓰기    숫자만    정해진 값. 없으면 ,
 
numbers.formatDecimal( 숫자, 끊을 단위, 사이에 삽입되는 문자, 표현되길 원하는 소숫점 자리, 소숫점이 시작되는 자리에 찍힐 문자) : 소숫점을 꾸며서 표현하고 싶을때 사용한다. 처음 세개의 매개변수는 Integer과 똑같이 작용하지만, 4번째                 매개 변수는  소숫점 몇번째 자리까지 표현할지 지정하며, 다섯번째 매개 변수는 소숫점이 시작되는 자리에 무엇을             넣을지 정한다. 쉼표나 공백이 들어갈수도 있다.
 
이외에도 다양한 함수와 명령어들이 존재하며, numbers에 list나 set같은 타입을 넣을수 있도록 해주는 함수도 존재한다. 이는 필요할때마다 공식 사이트를 참조하자

'공부 > java' 카테고리의 다른 글

자바 데이터 타입 변환(형변환)  (0) 2023.01.22
자바(java)의 데이터 타입  (0) 2023.01.22
자바(java)의 출력 함수  (0) 2023.01.22
19일차  (0) 2022.12.08
18일차 복습  (0) 2022.12.08