Spring Boot에는 Model, View, Controller의 유기적 역할 분담이 존재한다. Controller는 client로부터 요청을 받고, View는 최종 페이지를 만들어주고, Model은 최종 페이지에 쓰일 data들을 view에게 전달한다.
[chap2] 리뷰
전 시간에 localhost:8080/hi에 접속하여 뷰 템플릿 페이지가 출력된 것을 확인하였다. controller는 GetMappling을 통해 사용자의 localhost:8080/hi 접속 요청을 받음과 동시에 niceToMeetYou() 메소드가 수행되어 뷰 페이지를 보여준다. 또한 뷰 페이지에서 변수를 사용하기 위해선 model을 이용해 해당 변수와 값을 등록해야 한다.
이제 localhost:8080/bye라는 또다른 페이지를 만들어보자.
위와 같이 goodbye.mustache 파일을 작성하자.
그다음, Controller을 새로 만들어도 되지만 일단 기존에 사용했던 Controller1에 localhost:8080/bye 요청을 받아 goodbye 페이지를 반환하는 메소드 seeYouNext()를 작성하자.
localhost:8080/bye에 접속하면 정상적으로 출력된다.
이제 뷰 템플릿 페이지에 레이아웃을 나누는 연습을 할 것이다. 레이아웃이란 화면에 요소를 배치하는 방법이다. 그 중 가장 기본이 되는 레이아웃은 헤더-푸터 레이아웃이다.
헤더-푸터는 위 그림과 같은 샌드위치 같은 구조를 가진다. 보통 header 영역에는 사이트의 안내를 위한 Navigation을 넣고, footer 영역에는 사이트의 정보를 기록한다. 그리고 이 둘 사이에 사용자가 볼 핵심 내용들(content)을 보여준다.
지금부터 뷰 페이지에 헤더-푸터 레이아웃을 적용해보자. 👨💻
먼저 greetings를 세 영역 navigation, content, information으로 나눌 것이다. bootstrap에 접속하여 5.0 버전의 starter template을 적용한다.
먼저 우리는 위 그림의 빨간 박스, header 영역에 navigation을 추가할 것이다. bootstrap의 Docs를 눌러 "Navbar"를 검색하자.
스크롤을 내려 위 코드가 보이면 copy한 뒤
navigation 영역에 붙여넣고 서버를 재시작하여 결과를 확인해보자.
상단에 NavBar가 생겨난 것을 확인할 수 있다.
이제 하단에 informaion을 넣어보자. site informaion 영역에 아래의 코드를 붙여넣자.
<!-- site info -->
<div class="mb-5 container-fluid">
<hr>
<p>ⓒ CloudStudying | <a href="#">Privacy</a> | <a href="#">Terms</a></p>
</div>
이번에는 서버를 재실행하지 않고 우측 상단의 망치 모양을 눌러(build) mustache 코드를 빠르게 반영해보자.
🚩 이때 주의할 점은, mustache 코드가 바뀌면 망치만 눌러도 되지만 java 코드가 바뀌면 서버를 재실행해야 한다.
하단에 사이트 정보가 들어간 것을 확인할 수 있다.
이번엔 가운데 content의 내용을 조금 수정해보자.
<!-- content -->
<div class="bg-dark text-white p-5">
<h1>{{username}}님, 반갑습니다.</h1>
</div>
우리는 localhost:8080/bye에도 위와 동일한 레이아웃을 적용하고 싶다. 이럴 때 레이아웃을 템플릿화를 하면 된다. 템플릿화란 위의 navigation이나 information 영역에 추가한 코드들을 하나의 파일로 만들어 변수화시키는 것이다.
예를 들어 우리는 goodbye에서 레이아웃을 위처럼 변수로 사용해서 적용하길 원한다. 이를 위해선 templates 파일 안에 header와 footer라는 파일을 별도로 만들어줘야 한다.
구분이 편리하도록 layouts 디렉토리를 만들고 그 안에 header.mustache와 footer.mustache를 생성한다.
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<!-- navigation -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav>
이제 greetings의 navigation 부분을 파일화한다. 위의 코드(처음부터 content 영역 바로 위까지)를 잘라내어 header.mustache에 붙여넣는다.
<!-- site info -->
<div class="mb-5 container-fluid">
<hr>
<p>ⓒ CloudStudying | <a href="#">Privacy</a> | <a href="#">Terms</a></p>
</div>
<!-- Optional JavaScript; choose one of the two! -->
<Script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>
마찬가지로 greetings의 information 부분을 파일화한다. 위의 코드(content 영역 바로 아래부터 끝까지)를 잘라내어 footer.mustache에 붙여넣는다.
이제 greetings와 goodbye에 레이아웃 템플릿을 삽입해보자.
이렇게 해서 header와 footer를 변수화, 즉 템플릿화해서 가져올 수 있게 되며, 코드가 훨씬 간결해진 것을 확인할 수 있다. 뷰 템플릿 파일(뷰 페이지)을 불러올 때는 '>'를 추가해주어야 한다.
결과를 확인해보자.