Post

[코딩 자율학습 스프링 부트 3 자바 백엔드 개발 입문] 2장. MVC 패턴 이해와 실습

[코딩 자율학습 스프링 부트 3 자바 백엔드 개발 입문] 2장. MVC 패턴 이해와 실습

“코딩 자율학습 스프링 부트 3 자바 백엔드 개발 입문” 도서 바로가기

2장. MVC 패턴 이해와 실습

2.1 뷰 템플릿과 MVC 패턴

2.1.1 뷰 템플릿이란

뷰 템플릿(View Template)은 웹 애플리케이션에서 사용자가 보게 될 화면(User Interface)을 담당하는 기술이다. 웹 페이지(View)를 하나의 공통된 틀(Template)로 미리 만들어 두고, 상황에 따라 필요한 변수(Data)를 동적으로 삽입하여 서로 다른 구성의 페이지를 유연하게 보여주는 역할을 한다.

만약 뷰 템플릿이 없다면 100명의 사용자에게 서로 다른 이름을 보여주기 위해 100개의 HTML 파일을 각각 만들어야 하겠지만, 뷰 템플릿을 사용하면 하나의 HTML 틀에 이름이 들어갈 ‘변수’만 지정해 두면 된다.

앞서 1장에서 스프링 부트 프로젝트를 생성할 때 의존성(Dependencies)으로 추가했던 머스태치(Mustache)가 바로 이러한 뷰 템플릿을 화면을 만들어내는 대표적인 도구(템플릿 엔진)이다.

2.1.2 MVC 패턴

웹 애플리케이션의 화면을 담당하는 뷰 템플릿은 간단히 ‘뷰(View)’라고도 부른다. 이 뷰가 제 역할을 다하기 위해서는 혼자가 아니라 ‘컨트롤러(Controller)’와 ‘모델(Model)’이라는 두 명의 동료가 필요하다. 이 세 가지 핵심 요소를 조합하여 웹 서비스를 구축하는 아키텍처 기법을 MVC 패턴이라고 한다.

각각의 역할은 다음과 같이 명확하게 분담되어 있다.

  • 컨트롤러(Controller): 클라이언트(사용자)의 요청(Request)을 가장 먼저 받아들이는 문지기이자 브레인이다. 요청에 따라 어떤 비즈니스 로직을 수행할지 결정하고, 서버에서 이를 처리하는 전반적인 제어 역할을 담당한다.
  • 모델(Model): 뷰에 보여줄 데이터나 컨트롤러가 처리한 결과 데이터를 관리하고 전달하는 역할을 한다. 쉽게 말해, 컨트롤러와 뷰 사이에서 데이터를 안전하게 실어 나르는 박스(혹은 데이터 그 자체)라고 이해할 수 있다.

이처럼 웹 페이지를 화면에 보여주는 뷰(View), 클라이언트의 요청을 받아 처리하는 컨트롤러(Controller), 그리고 이 과정에서 쓰이는 데이터를 관리하는 모델(Model)로 역할을 철저히 나누는 이유는 코드의 유지보수성과 확장성을 높이기 위해서다. 각자 자신의 역할에만 집중함으로써, 화면이 바뀌더라도 비즈니스 로직에 영향을 주지 않고 안정적으로 코드를 관리할 수 있게 된다. 사진1


2.2 MVC 패턴을 활용해 뷰 템플릿 페이지 만들기

2.2.1 뷰 템플릿 페이지 만들기

머스태치(Mustache)를 사용해 사용자에 보여줄 동적 화면의 첫 틀(뷰 템플릿)을 만들어 보겠다.

1. 머스태치 파일 생성하기

  • src/main/resources/templates/ 디렉터리 아래에 greetings.mustache 파일을 새롭게 생성한다.

2. 플러그인 설치하기

  • 파일을 생성하면 인텔리제이 상단에 Plugin supporting *.mustache files found라는 안내 배너가 나타납니다. 머스태치 문법 하이라이팅과 자동 완성을 지원받기 위해 우측의 [Install Handlebars/Mustache plugin] 버튼을 클릭한다. 사진2

  • 이어지는 플러그인 확인 창에서 [OK]를 눌러 설치를 완료한다. 플러그인이 적용되면 머스태치 파일을 HTML처럼 편하게 편집할 수 있다. 사진3

3. HTML 기본 템플릿 생성 및 본문 작성하기

  • 생성한 greetings.mustache 파일의 첫 줄에 doc를 입력한 뒤 [Tab] 키를 누르면, 코드 생성 기능(Emmet) 덕분에 기본 HTML5 서식 코드가 자동으로 완성된다.
  • 완성된 HTML 구조 안의 <body> 태그 내부에 화면에 보여줄 문구를 다음과 같이 추가한다.
1
<h1>홍팍님, 반갑습니다!</h1>

사진4)

이것으로 화면을 담당할 기초적인 뷰 템플릿(View) 페이지 작성을 완료했다. 이제 이 페이지를 브라우저에 띄워줄 ‘컨트롤러’를 만들 차례다.

2.2.2 컨트롤러 만들고 실행하기

웹 브라우저의 요청을 받아 우리가 만든 뷰 템플릿을 연결해 줄 컨트롤러를 구현해 보겠다.

1. 컨트롤러 클래스 생성

  • src/main/java/com.example.firstproject/ 아래에 controller 패키지를 새로 만든다.
  • 생성한 패키지 내부에 FirstController라는 이름의 자바 클래스 파일을 생성한다.

2. 컨트롤러 코드 구현 및 핵심 어노테이션 이해하기

클래스 내부에 브라우저의 요청을 처리할 메서드를 작성하고 스프링 부트 어노테이션을 부여한다. 사진5)

  • @Controller: 이 클래스가 웹 브라우저의 요청을 받아 처리하는 ‘컨트롤러’임을 스프링 부트에 알리는 선언이다. 이 어노테이션이 붙어야 스프링이 컴포넌트 스캔을 통해 컨트롤러로 인식하고 관리한다.
  • @GetMapping("/hi"): 클라이언트가 웹 브라우저 주소창에 localhost:8080/hi로 접속(HTTP GET 요청)했을 때, 이 요청을 접수하여 아래의 메서드와 연결(Mapping)해 주는 역할을 한다.
  • return "greetings";: 메서드가 성공적으로 실행된 후 반환할 뷰 템플릿의 이름이다. 값을 "greetings"로 적어 반환하면, 스프링 부트의 뷰 리졸버(View Resolver)가 알아서 templates 디렉터리에서 greetings.mustache 파일을 찾아 웹 브라우저로 렌더링하여 전송하게 된다.

핵심 요약 컨트롤러가 정상적으로 동작하려면 아래 3가지 단계가 유기적으로 연결되어야 한다.

  1. @Controller를 통한 컨트롤러 클래스 선언
  2. @GetMapping("/URL경로")를 통한 클라이언트 요청 접수
  3. return "템플릿파일명";을 통한 보여줄 페이지 반환

3. 최종 결과 확인하기

  • 스프링 부트 애플리케이션을 다시 실행(Restart)한다.
  • 웹 브라우저를 열고 localhost:8080/hi 페이지에 접속하여, 우리가 뷰 템플릿에 작성했던 문구가 화면에 정상적으로 출력되는지 확인한다. 사진6)

2.2.3 모델 추가하기

이전 단계에서는 화면에 “홍팍님, 반갑습니다!”라는 문구를 직접 고정해서 보여주었다. 하지만 실제 서비스에서는 로그인한 사용자의 이름에 따라 화면이 동적으로 바뀌어야 한다. 이를 가능하게 만드는 핵심 요소가 바로 모델(Model)이다.

모델을 알아보기 전에 먼저 일반 HTML 파일과 뷰 템플릿 파일이 어떻게 다른지 명확히 정리해 보자.

일반 HTML 파일과 뷰 템플릿 파일의 차이

사진7)

구분일반 HTML 파일 (Static)뷰 템플릿 파일 (Dynamic)
페이지 성격정적 페이지 (언제 접근해도 항상 동일한 화면)동적 페이지 (데이터에 따라 매번 바뀌는 화면)
데이터 특징데이터가 소스 코드 내에 고정(Hard-coded)됨외부 실시간 데이터가 화면에 주입(Injection)됨
작동 방식웹 브라우저가 서버에서 파일을 있는 그대로 읽어서 표시템플릿 내의 빈칸({{ }})에 데이터를 채운 후 표시

1단계: 뷰 템플릿(Mustache)에 변수 삽입하기

머스태치 문법을 사용하면 화면에 고정된 텍스트 대신 값이 들어갈 빈칸(변수)을 선언할 수 있다.

  • 머스태치 변수 형식: {{변수명}}
  • 기존에 고정되어 있던 ‘홍팍’이라는 텍스트를 외부에서 동적으로 채워 넣을 수 있도록 {{username}}이라는 변수로 수정해 준다.

src/main/resources/templates/greetings.mustache 파일을 열고 다음과 같이 수정한다.

1
<h1>{{username}}님, 반갑습니다!</h1>

2단계: 컨트롤러에서 모델(Model) 주입하고 데이터 등록하기

뷰 템플릿에 {{username}}이라는 빈칸을 만들었으니, 이제 컨트롤러가 이 빈칸을 채워줄 데이터를 배달해야 한다. 이때 사용하는 전송 상자가 바로 Model 객체다.

모델은 컨트롤러 메서드의 매개변수를 통해 받아올 수 있다. FirstController.java로 이동하여 niceToMeetYou() 메서드를 다음과 같이 수정한다.

사진8)

💡 참고: 매개변수에 Model model을 입력하면, 스프링 부트가 인식하여 org.springframework.ui.Model 패키지를 자동으로 임포트(Import)해 준다.

Model 객체가 준비되었다면, 이제 이 상자에 데이터를 담아 뷰(View)로 넘겨줄 차례다. 모델에 변수를 등록할 때는 addAttribute() 메서드를 사용한다.

  • 형식: model.addAttribute("변수명", "변숫값");
  • 의미: 지정한 “변숫값”을 머스태치 템플릿에 선언한 “변수명”이라는 이름으로 매칭하여 추가한다. 사진9) 이렇게 컨트롤러에서 담은 "hongpark"이라는 문자열 데이터가 greetings.mustache 파일의 {{username}} 위치로 들어가게 된다.

3단계: 최종 결과 확인하기

스프링 부트 서버를 재시작한 뒤, 웹 브라우저에서 localhost:8080/hi 주소로 다시 접속해 보자. 사진10)

코드에 직접 “홍팍”을 적지 않았음에도, 컨트롤러의 모델을 통해 넘겨준 데이터인 hongpark이 머스태치 변수 자리에 동적으로 주입되어 화면에 성공적으로 출력되는 것을 확인할 수 있다.


2.3 MVC의 역할과 실행 흐름 이해하기

앞서 두 번에 걸쳐 뷰 템플릿을 만들고, 컨트롤러를 통해 브라우저의 요청을 접수한 뒤, 모델을 이용해 동적인 데이터를 화면에 주입해 보았다. 이제 이 과정이 내부적으로 어떻게 유기적으로 맞물려 돌아가는지 전체적인 실행 흐름을 명확하게 짚고 넘어가겠다.

2.3.1 /hi 페이지의 실행 흐름

작성한 FirstController.java 코드를 바탕으로, 클라이언트가 /hi 경로로 접속했을 때 어떤 순서로 동작이 일어나는지 단계별로 분석해 보자.

  1. 컨트롤러 선언: 클래스 상단에 @Controller 어노테이션을 붙여, 스프링 부트에게 이 파일이 웹 브라우저의 요청을 처리하는 컨트롤러임을 선언한다.
  2. 요청 접수: 클라이언트(웹 브라우저)가 localhost:8080/hi 주소로 요청을 보내면, 컨트롤러가 이를 받아 매핑한다.
  3. 메서드 수행: /hi라는 요청이 들어옴과 동시에, 이 주소와 연결된 @GetMapping("/hi") 아래의 niceToMeetYou() 메서드가 자동으로 실행된다.
  4. 모델 객체 주입: 뷰 템플릿 페이지에서 동적으로 사용할 데이터를 등록하기 위해, 외부로부터 Model 객체를 매개변수(Model model)로 가져온다.
  5. 데이터 등록 및 동적 처리: model.addAttribute()를 통해 사용할 변수를 등록한다. 전달되는 변숫값에 따라 최종적으로 출력되는 뷰 템플릿 페이지의 내용이 동적으로 결정된다.
  6. 뷰 템플릿 파일 반환: 메서드 수행 결과로 "greetings"라는 문자열을 반환(return)한다. 이때 스프링 부트는 복잡한 전체 경로를 생략하고 파일 이름만 적어도, src/main/resources/templates/ 디렉터리에서 해당 명칭을 가진 뷰 템플릿 파일(greetings.mustache)을 알아서 찾아 웹 브라우저로 최종 전송(렌더링)한다.

💡 한 줄 요약 컨트롤러가 @GetMapping("/hi")를 통해 클라이언트의 요청을 받으면 niceToMeetYou() 메서드를 수행하는데, 이때 뷰 템플릿에서 사용할 변수(username)는 모델(Model)을 통해 등록하고, 메서드 반환값으로 greetings.mustache 파일을 찾아 화면을 보여준다.

2.3.2 /bye 페이지의 실행 흐름

배운 내용을 토대로 이번에는 새로운 페이지인 /bye 경로를 직접 설계하고 코드를 작성해 보겠다.

1. 컨트롤러 메서드 추가하기

먼저 기존의 FirstController 클래스 내부에 @GetMapping 어노테이션을 활용해 새로운 요청을 받을 준비를 한다.

  • 클래스 내부에 @GetMapping("/bye") 어노테이션을 새롭게 추가한다.
  • /bye 요청을 처리해 줄 seeYouNext() 메서드를 생성한다.
  • 반환값은 요청에 따라 보여줄 새로운 뷰 템플릿의 이름이 된다. 아직 뷰 템플릿 파일을 생성하지 않았으므로, 임의로 return "goodbye";라고 먼저 적어둔다.

사진11)

2. 뷰 템플릿 파일 생성하기

  • src/main/resources/templates/ 디렉터리 위치에 goodbye.mustache 파일을 새로 만든다.

3. HTML 기본 뼈대 구성 및 정적 텍스트 추가

  • 새 파일이 열리면 제일 윗줄에 doc를 입력한 뒤 [Tab] 키를 눌러 기본 HTML5 코드를 자동으로 생성한다.
  • 웹 브라우저 화면에 보일 본문 태그(<body>) 내부에 <h1>xx님, 다음에 또 만나요!</h1> 문구를 추가한다.

사진12)

4. 뷰 템플릿 파일 변수 처리

  • 화면의 특정 영역을 동적인 데이터로 채우기 위해, 고정되어 있던 xx님 부분을 머스태치 변수로 변경하자.
  • 변수명은 nickname으로 지정하여 코드를 다음과 같이 수정한다.
1
<h1>{{nickname}}님, 다음에 또 만나요!</h1>

사진13)

5. 컨트롤러에 모델(Model) 추가하여 변수 등록하기

뷰 템플릿에 구멍({{nickname}})을 뚫어두었으니, 이제 이 페이지를 반환하는 컨트롤러의 메서드(seeYouNext)에서 데이터를 주입해 주어야 한다.

  • seeYouNext() 메서드의 매개변수로 Model model 객체를 인지하여 받아온다.
  • 메서드 내부에서 model.addAttribute()를 사용해 템플릿에 심어둔 변수명과 매칭될 변숫값을 적어준다.
1
2
3
4
5
@GetMapping("/bye")
public String seeYouNext(Model model) {
    model.addAttribute("nickname", "홍길동");
    return "goodbye";
}

사진14)

6. 결과 확인하기

  • 프로젝트를 빌드 및 재시작한 뒤 웹 브라우저를 열어 localhost:8080/bye 주소로 접속한다.
  • 우리가 모델을 통해 주입한 "홍길동"이라는 값이 뷰 템플릿에 올바르게 전달되어 화면에 정상 출력되는지 확인한다. 사진15)

📝 요약

전체 과정을 다시 한번 정리하자면, 컨트롤러는 클라이언트의 요청을 @GetMapping("/bye") 어노테이션으로 받는다. 요청이 접수되면 메서드가 실행되면서 모델 객체 상자에 "nickname"이라는 키값으로 "홍길동"이라는 데이터를 담아 연결해 준다. 그 후 결괏값으로 goodbye를 반환하여, 최종적으로 goodbye.mustache파일 안에서 주입된 데이터를 사용해 동적인 화면을 완성하게 된다.


2.4 뷰 템플릿 페이지에 레이아웃 적용하기

웹 페이지의 완성도를 높이기 위해서는 요소를 알맞은 자리에 배치하는 설계 작업이 필요하다. 이를 위한 핵심 개념들을 먼저 정리해 보자.

  • 레이아웃(Layout): 웹 브라우저 화면에 텍스트, 이미지, 버튼 등의 다양한 요소를 보기 좋게 배치하는 일련의 작업을 말한다.
  • 헤더-푸터 레이아웃: 웹 서비스에서 가장 기본적이면서도 널리 쓰이는 표준 레이아웃 구조다.
    • 상단 헤더(Header) 영역: 사이트 로고나 페이지 이동을 위한 내비게이션 바(Navigation Bar)를 배치하여 사용자의 가이드를 돕는다.
    • 하단 푸터(Footer) 영역: 사이트의 소유권 정보(Copyright), 이용약관, 개인정보처리방침 등 서비스의 부가 정보를 넣는다.
    • 중앙 콘텐츠(Content) 영역: 헤더와 푸터 사이의 공간으로, 사용자가 실제로 보게 될 페이지별 핵심 내용을 배치한다.

2.4.1 /hi 페이지에 헤더-푸터 레이아웃 적용하기

1. 부트스트랩 홈페이지 접속 및 버전 선택

  • 부트스트랩 공식 홈페이지에 접속한다. 본 실습은 교재와 완벽히 동일한 환경을 구성하기 위해 v5.0.2 버전을 선택하여 진행한다.

2. 스타터 템플릿(Starter template) 코드 복사

  • 부트스트랩이 제공하는 기본 뼈대인 ‘Starter template’ 코드를 복사한다. 이 코드에는 부트스트랩 CSS와 JS를 CDN 형태로 불러오는 링크가 미리 포함되어 있어 별도의 설치 없이 바로 스타일을 적용할 수 있다. 오른쪽의 [Copy] 버튼을 클릭한다.

    사진16)

3. greetings.mustache에 코드 붙여넣기

  • 인텔리제이로 돌아와 greetings.mustache 파일의 기존 내용을 모두 지운 뒤, 방금 복사한 부트스트랩 스타터 템플릿 코드를 그대로 붙여넣는다. 사진17)

4. 본문 영역을 3단 레이아웃 구조로 나누기 이제 <body> 태그 내부를 앞서 언급한 헤더-콘텐츠-푸터의 3단 구조로 쪼개어 설계해 보겠다.

  • a. 주석으로 영역 구분하기: HTML 주석 표기를 사용하여 나중에 코드가 길어지더라도 쉽게 알아볼 수 있도록 navigation, content, site info 영역을 명확히 나눈다.
  • b. 콘텐츠 변경: 기존 스타터 템플릿에 있던 Hello, world! 문구를 지우고, 우리가 이전에 다루었던 동적 변수 코드를 넣어줍니다.

    1
    
      <h1>{{username}}님, 반갑습니다!</h1>
    

    사진18)

5. 1차 결과 확인

  • 서버를 실행하고 localhost:8080/hi로 접속해 본다. 부트스트랩 CSS 폰트 스타일이 기본 적용되어 깔끔하게 출력되는 것을 볼 수 있다. 사진19)

6. 헤더 영역에 내비게이션 바(Navbar) 추가하기

  • 부트스트랩 문서의 검색창에 ‘navbar’를 입력한 후 목록에서 Navbar 컴포넌트를 선택한다. (버전이 v5.0.2로 잘 유지되어 있는지 다시 확인)

7. 컴포넌트 특징 확인 및 코드 복사

  • 아래로 스크롤을 내리면 제공되는 다양한 내비게이션 바 컴포넌트 예시를 볼 수 있다. 부트스트랩의 Navbar는 브라우저 창 크기에 따라 형태가 자연스럽게 변하는 반응형 디자인(Responsive Design)이 기본 적용되어 있다.

    사진20) 8. 템플릿에 내비게이션 바 삽입

  • 다시 greetings.mustache 파일로 돌아와, 미리 명시해 둔 주석 바로 아래에 복사한 Navbar 코드를 붙여넣는다.

9. 2차 결과 확인

  • localhost:8080/hi 주소를 새로고침하여 상단에 멋진 내비게이션 바가 결합되었는지 확인한다. 사진21)

10. 푸터 영역에 사이트 정보(Site Info) 추가하기 동일한 방식으로 하단에 사이트 정보를 구현해 보겠다.

  • 주석 아래에 <div> 태그를 생성하고, 구분선 역할을 할 <hr> 태그와 저작권 문구를 담을 <p> 태그를 배치한다.

    사진22)

11. [Tip] 서버 재시작 없이 빌드 반영하기

  • 머스태치나 HTML 같은 화면단 코드를 수정할 때마다 매번 무거운 스프링 부트 서버를 껐다 켜는 것은 비효율적이다.
  • 인텔리제이 상단 도구 바에 있는 망치 아이콘(Build Project, 단축키: Ctrl+F9 또는 Cmd+F9)을 클릭하면, 서버 재시작 없이 수정된 코드가 빌드되어 브라우저에 바로 반영된다.

12. 3차 결과 확인

  • 새로고침을 해보면 하단에 깔끔한 구분선과 함께 링크가 걸린 푸터 영역이 완 완성된 것을 볼 수 있다.

    사진23)

  1. 콘텐트 영역의 간격을 넓혀 보겠다. 콘텐트 부분을 <div></div> 태그로 감싸고 부트스트랩에서 제공하는 class 속성을 추가한다. 배경 색상은 어둡게(bg-dark), 텍스트 색상은 하얗게(text-white), 상하좌우 여백은 5배(p-5)만큼 준다.

13. 콘텐츠 영역 스타일 가다듬기

본문 메시지가 너무 왼쪽 구석에 붙어 있어 답답해 보인다. 부트스트랩의 강력한 유틸리티 클래스 속성을 사용해 간격과 스타일을 넓혀보겠다.

사진24)

  • 사용된 부트스트랩 클래스 알아보기
    • bg-dark: 배경 색상을 어둡게 지정한다.
    • text-white: 텍스트 색상을 하얗게 지정한다.
    • text-center: 텍스트를 가운데 정렬한다.
    • p-5: 상하좌우 안쪽 여백(Padding)을 가장 큰 단계(5배)만큼 충분히 준다.

14. 최종 결과 확인하기

  • 망치 아이콘을 눌러 변경 사항을 빌드한 뒤 웹 브라우저를 확인한다. 사진25)

2.4.2 /bye 페이지에 헤더-푸터 레이아웃 적용하기

/bye 페이지에도 /hi 페이지와 똑같이 중앙에는 핵심 내용인 content를 배치하고, 상단에는 navigation, 하단에는 site info를 넣어 일관된 레이아웃을 구성해 보겠다. 하지만 새로운 페이지를 만들 때마다 매번 수십 줄짜리 부트스트랩 코드를 통째로 복사해서 붙여넣는 방식을 사용하면 코드가 너무 길어지고 유지가 비효율적이다. 따라서 기존의 /hi 페이지를 템플릿화하여 스마트하게 재사용하는 방식을 적용하겠다.

💡 템플릿화(Modularization)란? 반복적으로 사용되는 웹 페이지의 공통 코드를 하나의 독립된 틀(모듈)로 분리해 두고, 변수처럼 필요할 때마다 호출하여 조립하는 방식을 말한다.

템플릿 파일 만들고 적용하기(greetings.mustache)

1. 레이아웃 디렉터리 및 파일 생성

  • src/main/resources/templates/ 디렉터리 하위에 레이아웃 모듈을 모아둘 layouts 디렉터리를 새로 생성한다.
  • 그 다음, 분리해 낼 공통 틀이 될 header.mustache 파일과 footer.mustache 파일을 각각 생성한다.

2. 헤더(Header) 코드 분리하기

  • 기존에 완성해 두었던 greetings.mustache 소스 코드에서 상단 내비게이션 바 영역을 통째로 발췌(잘라내기)하여, 방금 만든 header.mustache 파일에 그대로 붙여넣는다. 사진26)

3. 헤더 템플릿 주입하기

  • 잘라내고 비어 있는 greetings.mustache 상단 자리를 외부 템플릿 모듈로 대체해야 한다.
  • 일반 데이터를 뷰 템플릿에 출력할 때는 {{변수명}} 형태를 사용하지만, 외부의 또 다른 뷰 템플릿 파일을 통째로 불러와 포함(include)할 때는 닫는 홀화살괄호(>)를 추가해 {{>파일경로}} 형식으로 작성한다.
  • 따라서 greetings.mustache 최상단에 {{>layouts/header}}라고 적어 템플릿을 호출한다.

4. 푸터(Footer) 코드 분리하기

  • 마찬가지로 greetings.mustache 코드의 하단 푸터 영역(~</html>) 역시 모두 드래그하여 잘라낸 뒤, footer.mustache 파일에 고스란히 옮겨 담아 준다. 사진27)

5. 푸터 템플릿 주입하기

  • 푸터 영역이 통째로 빠져나간 greetings.mustache 코드의 핵심 콘텐츠 영역 바로 아래에 {{>layouts/footer}} 코드를 추가해 준다. 이로써 변수 형태로 푸터 템플릿 파일을 깔끔하게 가져오도록 연동이 완료된다.

6. 정돈된 소스 코드 확인

  • 공통 레이아웃을 완벽하게 분리해 낸 결과, 기존 부트스트랩 코드로 복잡하고 길었던 greetings.mustache 코드가 단 몇 줄 만으로 매우 짧고 직관적으로 정돈된 것을 확인할 수 있다. 사진28) 7. 중간 결과 확인

  • 인텔리제이에서 프로젝트를 다시 빌드하고 웹 브라우저에서 localhost:8080/hi 페이지를 새로고침 해본다. 내부 코드를 완전히 조각내어 재조립했음에도 불구하고 기존 화면과 다름없이 문제없이 잘 작동되는 것을 확인할 수 있다.

템플릿 적용하기(goodbye.mustache)

레이아웃 모듈화 작업을 마쳤기 때문에, 이제 새로 만드는 페이지에는 아주 손쉽게 디자인 통일성을 부여할 수 있다.

1. goodbye.mustache 파일도 다음과 같이 완성한다.

a. 기존의 goodbye.mustache 파일로 이동하여 중심 콘텐츠 영역인 <h1> 태그만 남겨두고 불필요한 기존 기본 HTML 코드는 모두 지워준다. 그 다음 상단과 하단에 각각 헤더 템플릿({{>layouts/header}})과 푸터 템플릿({{>layouts/footer}})을 삽입해 준다.

b. 중앙 콘텐츠 영역 역시 앞서 구현한 페이지와 통일감 있는 스타일을 갖추도록 <div> 태그로 감싸고, 동일한 부트스트랩의 class 속성(class="bg-dark text-white text-center p-5")을 그대로 적용해 코드를 완성해 준다.

사진29)

2. 결과 최종 확인

  • 모든 레이아웃 연동 마친 뒤, 웹 브라우저 주소창에 localhost:8080/bye 페이지를 새로고침 하여 접근해 본다. 복잡한 스타일 코드를 직접 선언하지 않았음에도, 상단 내비게이션 바와 하단 푸터 레이아웃이 깨짐 없이 문제없이 깔끔하게 잘 나오는 것을 직접 확인할 수 있다.
This post is licensed under CC BY 4.0 by the author.