홈 컨트롤러 등록
package jpabook.jpashop.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@Slf4j
public class HomeController {
@RequestMapping("/")
public String home() {
log.info("home controller");
return "home";
}
}
스프링부트 타임리프 기본설정
spring:
thymeleaf:
prefix: classpath:/templates/
suffix: .html
스프링부트 타임리프 viewName 매핑
resources:templates/ + {ViewName} + .html
resources:templates/home.html
반환한 문자(home)와 스프링부트 설정 prefix, suffix 정보를 사용해서 렌더링할 뷰(html)를 찾는다.
타임리프 템플릿 등록
templates/home.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/header :: header">
<title>Hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div class="container">
<div th:replace="fragments/bodyHeader :: bodyHeader" />
<div class="jumbotron">
<h1>HELLO SHOP</h1>
<p class="lead">회원 기능</p>
<p>
<a class="btn btn-lg btn-secondary" href="/members/new">회원 가입</a>
<a class="btn btn-lg btn-secondary" href="/mebers">회원 목록</a>
</p>
<p class="lead">상품 기능</p>
<p>
<a class="btn btn-lg btn-dark" href="/items/new">상품 등록</a>
<a class="btn btn-lg btn-dark" href="/items">상품 목록</a>
</p>
<p class="lead">주문 기능</p>
<p>
<a class="btn btn-lg btn-info" href="/order">상품 주문</a>
<a class="btn btn-lg btn-info" href="/orders">주문 내역</a>
</p>
</div>
<div th:replace="fragments/footer :: footer" />
</div> <!-- /container -->
</body>
</html>
templates/fragments/header.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="header">
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="/css/bootstrap.min.css" integrity="sha384-
ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
crossorigin="anonymous">
<!-- Custom styles for this template -->
<link href="/css/jumbotron-narrow.css" rel="stylesheet">
<title>Hello, world!</title>
</head>
templates/fragments/bodyHeader.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div class="header" th:fragment="bodyHeader">
<ul class="nav nav-pills pull-right">
<li><a href="/">Home</a></li>
</ul>
<a href="/"><h3 class="text-muted">HELLO SHOP</h3></a>
</div>
templates/fragments/footer.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div class="footer" th:fragment="footer">
<p>© Hello Shop V2</p>
</div>
결과화면
참고 : Hierarchical-style layouts
예제에서는 뷰 템플릿을 최대한 간단하게 이해하려고 header, footer 같은 템플릿 파일을 반복해서 포함한다.
다음 링크의 Hierarchical-style layouts를 참고하면 이런 부분도 중복을 제거할 수 있다.
http://www.thymeleaf.org/doc/articles/layouts.html
Thymeleaf Page Layouts - Thymeleaf
Summary In this article, we described many ways of achieving the same: layouts. You can build layouts using Thymeleaf Standard Layout System that is based on include-style approach. You also have powerful Layout Dialect, that uses decorator pattern for wor
www.thymeleaf.org
참고 : 뷰 템플릿 변경사항을 서버 재시작 없이 즉시 반영하기
1. spring-boot-devtools 추가
2. html 파일 build -> Recompile
view 리소스 등록
예쁜 디자인을 위해 부트스트랩을 사용하겠다.
v5.3.5 다운로드 : https://getbootstrap.com/
Bootstrap
Powerful, extensible, and feature-packed frontend toolkit. Build and customize with Sass, utilize prebuilt grid system and components, and bring projects to life with powerful JavaScript plugins.
getbootstrap.com
resources/static 하위에 css, js 추가
resources/static/css/jumbotron-narrow.css 추가
resources/static/css/jumbotron-narrow.css
/* Space out content a bit */
body {
padding-top: 20px;
padding-bottom: 20px;
}
/* Everything but the jumbotron gets side spacing for mobile first views */
.header,
.marketing,
.footer {
padding-left: 15px;
padding-right: 15px;
}
/* Custom page header */
.header {
border-bottom: 1px solid #e5e5e5;
}
/* Make the masthead heading the same height as the navigation */
.header h3 {
margin-top: 0;
margin-bottom: 0;
line-height: 40px;
padding-bottom: 19px;
}
/* Custom page footer */
.footer {
padding-top: 19px;
color: #777;
border-top: 1px solid #e5e5e5;
}
/* Customize container */
@media (min-width: 768px) {
.container {
max-width: 730px;}
}
.container-narrow > hr {
margin: 30px 0;
}
/* Main marketing message and sign up button */
.jumbotron {
text-align: center;
border-bottom: 1px solid #e5e5e5;
}
.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}
/* Supporting marketing content */
.marketing {
margin: 40px 0;
}
.marketing p + h4 {
margin-top: 28px;
}
/* Responsive: Portrait tablets and up */
@media screen and (min-width: 768px) {
/* Remove the padding we set earlier */
.header,
.marketing,
.footer {
padding-left: 0;
padding-right: 0;
}
/* Space out the masthead */
.header {
margin-bottom: 30px;
}
/* Remove the bottom border on the jumbotron for visual effect */
.jumbotron {
border-bottom: 0;
}
}
'Backend' 카테고리의 다른 글
[실전! 스프링부트와 JPA활용] 웹계층 개발 - 회원 목록 조회 (0) | 2025.04.12 |
---|---|
[실전! 스프링부트와 JPA활용] 웹계층 개발 - 회원 등록 (0) | 2025.04.11 |
[실전! 스프링부트와 JPA활용] 주문검색 기능개발 : JPQL, JPA Criteria, Querydsl (0) | 2025.04.09 |
[실전! 스프링부트와 JPA활용] 주문 기능 테스트 / JUnit5의 assertEquals 사용순서 (0) | 2025.04.08 |
[실전! 스프링부트와 JPA활용] 주문 서비스 개발 / 도메인 모델 패턴 vs 트랜잭션 스크립트 패턴 (0) | 2025.04.07 |