2019. 10. 21. 14:25ㆍSpring/Spring Boot Tutorial
Thymeleaf template engine?
spring 기반 웹 애플리케이션의 뷰 페이지에서 html, xml, javascript, css, text 처리 후 웹 브라우저에 표시할 때 이용되는 템플릿 엔진의 일종으로 JSP보다 빠르다는 장점이 있습니다.
※ 이전과정에 이어서 진행됩니다.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> </dependency>
이번 과정에서 타임리프 템플릿 이용을 위해 필요한 의존성 라이브러리는 위와 같습니다.
thymeleaf 스타터 폼과 springsecurity 사용을 위한 라이브러리를 추가합니다.
Layout Dialect는 이번 과정에서 다루지 않기 때문에 추가하지 않았습니다.
spring: mvc: static-path-pattern: /static/** thymeleaf: mode: HTML encoding: UTF-8 check-template-location: true prefix: classpath:/templates/ suffix: .html cache: false resources: static-locations: - classpath:/static/ cache: period: 0
타임리프와 관련된 프로퍼티 키 값입니다.
위에 설정된 값들 중, sprirng.mvc.static-path-pattern
과 spring.thymeleaf.cache
, spring.resources.static-locations
그리고 spring.resources.cache.period
를 제외한 나머지 요소들은 모두 디폴트 값입니다.
타임리프 템플릿 관련 설정
- ln 6: 기본 인코딩 값을 바꾸고 싶을 경우 설정
- ln 8: 템플릿 문서 경로를 변경하고 싶을 경우. 설정한다. 디폴트는
classpath:/templates/
이기 때문에, 아래 [그림 7-1] 문서 구조에서main.html
문서를 열고자 할때에는classpath:/templates/content/main.html
에서 prefix와 suffix를 제외하고 content/main 이라고 작성하면 됩니다. 만약, [그림 7-2]의 위치에 템플릿을 위치시키고 싶다면,WEB-INF/templates
라고 설정해주면 됩니다.
[그림 7-1]
[그림 7-2] - ln 10: 타임리프 템플릿 문서의 캐시 사용 유무 설정. 로컬 테스트 환경에서는 false로 설정하고 실서버에서는 true로 설정하는 것을 권장합니다.
정적파일(js, css, images) 관련 설정
- ln 3: 정적파일로 인식할 prefix 패턴. default값은 /** 입니다.
- ln 12~13: 정적파일 위치. 만일 정적파일의 위치를 변경하고자 한다면 이 값을 변경해 주면 됩니다.
- ln 15: 정적파일의 캐시 유효기간을 설정합니다.
템플릿 관련 설정을 모두 마쳤다면, 이젠 템플릿 문서를 만들러 가야겠네요.
<html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
먼저, 문서의 root 요소인 <html>
에 타임리프를 사용하기 위해 필요한 xml namespace를 설정합니다.
우리는 th와 sec xml 네임스페이스를 추가했습니다.
html로 문서를 만들거에요.
<body>
내에 <header>, <nav>, <section>, <footer>
를 성질에 따라 구분을 하여 레이아웃 디자인을 할 예정입니다.
그 틀안에서 컨텐츠가 들어갈 부분은 아래와 같습니다.
웹 디자인은 개발자가 새로이 지식을 얻는것은 어려움이 많기 때문에 저는 부트스트랩을 이용하여 그리드 디자인을 할 것입니다.
만약, 부트스트랩에 대한 지식이 필요하다면, w3schools.com 사이트를 참고해주세요.
- 맨위에는 로고와 회원정보 및 로그아웃 버튼이 위치할 header
- 네비게이션 바(메뉴)가 위치할 nav
- 페이지에 따라 내용이 바뀔 section
- 웹페이지 정보 및 기타 링크가 위치할 footer
1. header
<header> <a th:href="@{/v}"><img th:src="@{/static/img/like.png}" width="50" height="auto" alt="demo page" id="btn_home" /></a> <ul> <li sec:authorize="isAuthenticated()"> <span sec:authentication="principal.username"></span> 님 반가워요! </li> <li><form id="logoutFrm" th:action="@{/logout}" method="post" style="display: inline-block;"> <a href="#" onclick="document.getElementById('logoutFrm').submit()" data-toggle="tooltip" data-placement="logout" title="Logout"><i class="fa fa-power-off"></i></a> </form></li> </ul> </header>
ln 2: 정적파일인 이미지파일의 경로는 classpath:/static 폴더 아래의 /img에 위치합니다. 타임리프 템플릿에서는 contextpath를 th:src="@{}" 와 같이 th xml 네임스페이스를 이용해서 주소를 자동 세팅할 수 있습니다. 기존의 src를 이용하면 자동을 설정하지 못하지 주의 해야합니다.
ln 4~5: sec xml 네임스페이스를 이용하여 spring security 인가 정보를 이용할 수 있습니다. 인증된 사용자의 경우 username을 가져와서 표기하도록 설정했습니다.
만일, 인증되지 않은 사용자의 경우 이 li태그 포함 하위 태그는 페이지에 표시되지 않습니다.
2. nav
<nav class="navbar navbar-expand-lg navbar-light" id="nav_area"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#nav_menu_area"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="nav_menu_area"> <ul class="navbar-nav" id="n_menu"> <li class='nav-item' th:classappend="${currentPage eq 'home'} ? 'active' : ''" th:attr="data-href=@{/v}">홈</li> <li sec:authorize="hasRole('ROLE_ADMIN')" class='nav-item' th:classappend="${currentPage eq 'user'} ? 'active' : ''" th:attr="data-href=@{/v/users}">회원</li> </ul> </div> </nav>
ln 8~9: 네비게이션 바에 있는 메뉴를 클릭 할 시, 선택된 메뉴를 active 처리하기 위해 ${currentPage}
속성을 이용한다. th:classappend를 이용하여 만일 currentPage가 home일 경우 active 클래스를 추가한다.
ln 10: 로그인한 사용자가 'ROLE_ADMIN' 롤을 가지고 있을 경우에만 회원 메뉴가 생성되도록 인가처리를 했다.
3. section, footer
<section> <div class="container"> <div class="d-title"> <h2>thymeleaf tutorial 과정</h2> </div> <div class="d-content"> <div class="row"> <ul> <li>thymeleaf 관련 configuration 설정하기</li> <li>thymeleaf로 웹 페이지 구성하기</li> <li>JSP vs thymeleaf 비교하기</li> <li>thymeleaf layout 구성하기</li> </ul> </div> </div> </div> </section> <footer> <p> JINI WORLD - DEMO </p> </footer>
section 영역에는 컨텐츠를 입력하고, footer에 바닥글을 설정합니다.
(타임리프 기능을 사용한 것이 없기에 별도의 추가 설명은 생략합니다.)
위의 코드들에 css를 적용한 결과입니다.
이번에는, 회원 페이지를 만들어볼까요?
회원 페이지의 경우, <header>, <nav>, <footer>
태그 내용은 그대로 사용하고, <section>
태그만 새로 정의하면 됩니다.
d-title에 'user 조회' 라고 설정하고, d-content에 회원리스트 5개를 테이블 안에 담아서 보여줄 건데요.
나머지 부분은 생략하고, d-content
내용을 살펴보도록 할거에요.
<div class="d-content"> <div class="row"> <div class="table-responsive"> <table class="table table-striped"> <thead> <tr class="text-center"> <th width="10%">아이디</th> <th width="6%">유형</th> <th width="10%">이름</th> <th width="15%">전화번호</th> <th width="10%">생일</th> <th width="7%">성별</th> <th width="25%">가입일시</th> <th width="7%">탈퇴여부</th> </tr> </thead> <tbody> <tr class="text-center" th:object="${user}" th:each="user: ${users}" th:attr="data-href=@{/v/users/__${user.id}__}"> <td th:text="*{ id }"></td> <td th:text="*{ type eq '0' ? '일반' : eq '1' ? '사업자' : '미설정' }"></td> <td th:text="*{ name }"></td> <td th:text="*{ phoneNumber }"></td> <td th:text="*{ birthDate }"></td> <td th:text="*{ sex eq '1' ? '남자' : sex eq '2' ? '여자' : '미설정' }"></td> <td th:text="*{ createTimestamp }"></td> <td th:text="*{ del ? 'Y' : 'N' }"></td> </tr> </tbody> </table> </div> </div> </div>
ln 18: users 객체에는 user 엔티티 5개가 들어있습니다. 그 리스트를 th:each
로 tr 태그를 하나씩 생성하는데요. 이 공통적인 user 객체를 th:object
로 정의하면 하위 <td>
태그에서는 ${user.id}
에서 user.
prefix를 생략할 수 있어서 가독성을 높일 수 있습니다.
ln 20: type이 '0'일 경우 '일반', '1' 일 경우 '사업자', 그 외의 경우에는 '미설정' 으로 표기하도록 했습니다. null값이 들어있을 경우에도 '미설정'으로 출력됩니다.
상세한 코드를 확인해보고 싶다면, 아래의 GitHub 주소에서 소스코드를 다운받아서 확인해보세요.
참고로 이번 과정에서는 레이아웃 설정하는 방법을 다루지 않았기 때문에
home 과 user 페이지에서 공통적으로 사용하고 있는 <header>, <nav>, <footer>
태그 내의 내용을 중복해서 작성했습니다.
다음 과정에서는 이런 중복되는 정보를 레이아웃으로 설정하는 방법을 알아볼 것입니다.
※ GitHub에서 demo 프로젝트를 다운받아 볼 수 있습니다.
'Spring > Spring Boot Tutorial' 카테고리의 다른 글
[Spring Boot Tutorial] 7. JavaConfig 설정으로 Spring Security 커스터마이징 (2) | 2019.11.29 |
---|---|
[Spring Boot Tutorial] 6. Thymeleaf layout 설정하기 (3) | 2019.10.30 |
[Spring Boot Tutorial] 4. Spring security 맛보기 (0) | 2019.10.04 |
[Spring Boot Tutorial] 3. JPA CRUD (6) | 2019.09.16 |
[Spring Boot Tutorial] 2. MySQL + JPA 설정 (1) | 2019.09.09 |