- 해당 게시물은 인프런 - "스프링 MVC 2편 - 백엔드 웹 개발 활용 기술" 강의를 참고하여 작성한 글 입니다.
- 유료강의이므로 자세한 내용은 없고, 간단한 설명 위주로 정리했습니다.
강의 링크 -> 김영한 - 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술(유료강의)
스프링 부트 스타터에서 프로젝트를 생성한다.
타임리프
백엔드 서버에서 HTML을 동적으로 렌더링
순수 HTML을 최대한 유지
타임리프를 사용할 때에 다음 코드를 선언해 준다.
<html xmlns:th="http://www.thymeleaf.org">
java/hello/thymeleaf/basic/BasicController
model에 "data"라는 이름으로 "hello Spring!"를 넣어서, 뷰 템플릿을 호출한다.
model.addAttribute("data","hello Spring!");
return "basic/text-basic";
resources/templates/basic/text-basic.html
model에 담은 data를 출력하기 위해
th:text="${data}"
또는 [[${data}]]
를 사용한다.
<li>th:text 사용 <span th:text="${data}"></span></li>
<li>컨텐츠 안에서 직접 출력하기 = [[${data}]]</li>
실행해보면 정상적으로 data의 내용이 찍히는 것을 볼 수 있다.
만약 model에 담긴 내용에 html 태그를 추가해서 실행하면
model.addAttribute("data","hello <b>Spring!</b>");
문자 그대로가 출력이 되고, 내가 원하는 html 태그로 렌더링 되지 않는다.
왜냐하면 타임리프의 이스케이스(escape) 기능 때문이다.
그래서 이스케이프(escape)를 사용하지 않는 기능을 사용할 수 있다.
resources/templates/basic/text-basic.html
model에 담은 data를 이스케이프(escape) 를 사용하지 않도록 출력하기 위해
th:utext="${data}"
또는 [(${data})]
를 사용한다.
<li>th:utext = <span th:utext="${data}"></span></li>
<li><span th:inline="none">[(...)] = </span>[(${data})]</li>
그러면 model에 담긴 html 태그가 정상적으로 작동하는 것을 볼 수 있다.
타임리프에서 변수를 사용할 때는 변수 표현식을 사용한다.
java/hello/thymeleaf/basic/BasicController
변수 표현식을 사용하기 위해, User 객체를 새로 생성한다.
@Data
static class User {
private String username;
private int age;
메서드에 객체를 생성하여 값을 넣고
model에다가 객체, List, Map을 넣어 뷰 탬플릿을 호출한다.
// userA 객체 생성
User userA = new User("userA", 10);
// List에 userA 객체 넣음
List<User> list = new ArrayList<>();
list.add(userA);
// Map에 userA 객체 넣음
Map<String, User> map = new HashMap<>();
map.put("userA", userA);
// model에 객체, List, Map 넣음
model.addAttribute("user", userA);
model.addAttribute("users", list);
model.addAttribute("userMap", map);
return "basic/variable";
resources/templates/basic/variable.html
객체, List, Map 변수에 담긴 내용을 다음 문법을 사용하여 출력한다.
<!-- 객체 -->
<span th:text="${user.username}"></span>
<span th:text="${user['username']}"></span>
<span th:text="${user.getUsername()}"></span>
<!-- List -->
<span th:text="${users[0].username}"></span>
<span th:text="${users[0]['username']}"></span>
<span th:text="${users[0].getUsername()}"></span>
<!-- Map -->
<span th:text="${userMap['userA'].username}"></span>
<span th:text="${userMap['userA']['username']}"></span>
<span th:text="${userMap['userA'].getUsername()}"></span>
그러면 변수의 담긴 내용이 제대로 출력되는 것을 볼 수 있다.
추가적으로 th:with
를 사용하면 지역 변수를 선언해서 사용할 수 있으며,
이는 선언한 태그 안에서만 사용할 수 있다.
<div th:with="first=${users[0]}">
<p>처음 사람의 이름은 <span th:text="${first.username}"></span></p>
</div>
실행을 하면 지역 변수가 출력되는 것을 볼 수 있다.
타임리프가 제공하는 객체
${#request}
${#response}
${#session}
${#servletContext}
${#locale}
java/hello/thymeleaf/basic/BasicController
타임리프가 제공하는 기본 객체와 요청 파라미터, 세션, 스프링 빈을 사용하기 위해
세션 데이터를 넣고 스프링 빈을 생성한다.
@GetMapping("/basic-objects")
public String basicObjects(HttpSession session) {
session.setAttribute("sessionData", "Hello Session"); // 세션
return "basic/basic-objects";
}
@Component("helloBean") // 스프링빈 등록
static class HelloBean {
public String hello(String data) {
return "Hello " + data;
}
}
resources/templates/basic/basic-objects.html
우선 기본적으로 제공하는 객체를 아래와 같이 사용할 수 있다.
<span th:text="${#request}"></span>
<span th:text="${#response}"></span>
<span th:text="${#session}"></span>
<span th:text="${#servletContext}"></span>
<span th:text="${#locale}"></span>
실행을 하면 해당 객체들의 정보가 출력된다.
그리고 HTTP 요청 파라미터 정보, 세션 정보, 스프링 빈 정보를 아래와 같이 사용해 출력할 수 있다.
<span th:text="${param.paramData}"></span>
<span th:text="${session.sessionData}"></span>
<span th:text="${@helloBean.hello('Spring!')}"></span>
타임리프는 문자, 숫자, 날짜, URI 등을 편리하게 다루는 다양한 유틸리티 객체들을 제공한다.
java/hello/thymeleaf/basic/BasicController
타임리프가 제공하는 유틸리티 객체를 사용하기 위해 현재 시간을 model에 담는다.
model.addAttribute("localDateTime", LocalDateTime.now()); // 현재 시간 담음
return "basic/date";
resources/templates/basic/date.html
model에 넣은 현재 시간을 알려주는 localDateTime를 다음과 같이 사용하고, format을 지정하여 출력할 수 있다.
<span th:text="${localDateTime}"></span>
<span th:text="${#temporals.format(localDateTime, 'yyyy-MM-dd HH:mm:ss')}"></span>
그리고 타임리프가 제공하는 유틸리티 객체도 다음과 같이 사용한다.
<span th:text="${#temporals.day(localDateTime)}"></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>
<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 링크를 생성할 수 있다.
java/hello/thymeleaf/basic/BasicController
URL 링크를 생성할 때, 경로에 넣을 값을 model에 넣고 뷰 템플릿을 호출한다.
model.addAttribute("param1", "data1");
model.addAttribute("param2", "data2");
return "basic/link";
resources/templates/basic/link.html
일반적인 단일 경로는 아래와 같이 사용한다.
<!-- http://localhost:8080/hello -->
<a th:href="@{/hello}">
쿼리 파라미터를 넣은 경로는 아래와 같이 사용하며,
()
에 있는 부분은 쿼리 파라미터로 처리된다.
<!-- http://localhost:8080/hello?param1=data1¶m2=data2 -->
<a th:href="@{/hello(param1=${param1}, param2=${param2})}">
다중 경로는 아래와 같이 사용하며,
경로에 변수가 있으면 ()
부분이 경로 변수로 처리된다.
<!-- http://localhost:8080/hello/data1/data2 -->
<a th:href="@{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})}">
쿼리 파라미터 + 다중경로는 아래와 같이 사용한다.
<!-- http://localhost:8080/hello/data1?param2=data2 -->
<a th:href="@{/hello/{param1}(param1=${param1}, param2=${param2})}">
리터럴 - 소스 코드상에 고정된 값
- 문자:
'hello'
<- 항상 '작은 따옴표'로 감쌈(공백 없으면 생략 가능)- 숫자:
10
- 불린:
true
,false
- null:
null
java/hello/thymeleaf/basic/BasicController
리터럴을 사용하기 위해 model에 문자열을 담아 뷰 템플릿을 호출한다.
model.addAttribute("data", "Spring!");
return "basic/literal";
resources/templates/basic/literal.html
+ 를 사용하여 리터럴을 연결할 수 있으며, 문자열 변수도 연결할 수 있고
th:text="|hello ${data}|"
로 리터럴 대체 문법을 사용할 수도 있다.
<span th:text="'hello' + ' world!'"></span>
<span th:text="'hello world!'"></span>
<span th:text="'hello ' + ${data}"></span>
<span th:text="|hello ${data}|"></span>
타임리프에서 연산을 사용할 수 있으며, 자바와 크게 다르지 않다.
java/hello/thymeleaf/basic/BasicController
연산을 사용하기 위해 null 값과 문자열을 model에 넣고 뷰 템플릿을 호출한다.
model.addAttribute("nullData", null);
model.addAttribute("data", "Spring!");
return "basic/operation";
resources/templates/basic/operation.html
산술 연산을 하여 연산의 답과 연산의 결과가 true인지 false 인지 알 수 있다.
<span th:text="10 + 2"></span>
<span th:text="10 % 2 == 0"></span>
비교 연산을 할 때, html 태그인 >, <를 유의하며, 연산의 결과는 true, false로 출력된다.
<span th:text="1 > 10"></span>
<span th:text="1 gt 10"></span>
<span th:text="1 >= 10"></span>
<span th:text="1 ge 10"></span>
<span th:text="1 == 10"></span>
<span th:text="1 != 10"></span>
조건식은 삼항연산자를 사용하여 조건에 따라 값이 출력된다.
<span th:text="(10 % 2 == 0)? '짝수':'홀수'"></span>
Elvis 연산자를 사용하여 true이면 해당 변수를, false이면 '데이터가 없습니다.'가 출력된다.
<span th:text="${data}?: '데이터가 없습니다.'"></span>
<span th:text="${nullData}?: '데이터가 없습니다.'"></span>
No-Operation을 사용하여 변수 값이 없으면 html의 값이 그대로, 있으면 변수가 출력된다.
<span th:text="${data}?: _">데이터가 없습니다.</span>
<span th:text="${nullData}?: _">데이터가 없습니다.</span>
지금까지 김영한 - 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술(유료강의) 강의를 참고하여 타임리프 - 기본 기능 1 에 대해 공부하였다.