애플리케이션이 제대로 동작하는 것은 확인했지만, 아직 화면을 만들지 않아 에러 페이지가 뜨고있다. 이제 URL에 따라 적당한 화면이 띄어지도록 만들어보면서 스프링 부트가 동작하는 흐름을 파악해 보도록 하자.
우선 사용자가 주소창에 도메인을 입력하고 들어오면 가장 먼저 보게 될 Welcome Page를 작성한다. 스프링 부트는 resources > static
안에 index.html
파일을 작성해 넣어두면 이 index.html
을 알아서 Welcome Page로 띄워준다 (이 내용은 스프링 부트 문서에서 Welcome Page 검색하면 확인할 수 있다). resources > static > index.html
를 만들고 아래 코드를 작성해서 실행한 후 localhost:8080
을 접속해보면 에러 페이지 대신 내가 작성한 Welcome Page가 뜨는 것을 볼 수 있다.
<!-- resources > static > index.html -->
<!DOCTYPE HTML>
<html>
<head>
<title>스프링 입문</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head>
<body>
Hello! This is my Welcome Page!
</body>
</html>
Welcome Page 말고도 다른 페이지들을 추가하려면 어떻게 해야할까? 예를 들어, 특정 url을 호출해 자기소개 페이지로 넘어가면서 서버가 넘겨준 값들을 출력하도록 구현하기 위해서는 스프링 부트가 동작하는 흐름을 알고 있어야 한다. 김영한(강사) 님의 강의자료를 참조하여 위 예제에 맞게 스프링 부트의 동작 흐름을 그림으로 나타내 보았다.
자기소개 페이지에 접속하기 위해 웹 브라우저에localhost:8080/hello
라는 url을 입력하면, 스프링 부트의 내장 톰캣 서버가 컨트롤러 안에서 hello
라는 이름에 GET 방식으로 매핑 되어있는 메서드를 찾아 호출한다. 여기서 컨트롤러는 요청에 따라 적절한 비즈니스 로직을 수행한 후 그 결과를 뷰에 전달하는 역할을 수행한다.
컨트롤러에서는 화면에 전달할 속성들을 model
이라는 객체에 담을 수 있다. 아직 DB 접근에 대해 다루기 전이니, 일단 임의의 값을 담아보도록 하자. model
에는 속성의 이름과 그에 해당하는 속성의 값을 매핑해야 하는데, 속성 이름은 "nickname"
, 속성 값은 "콜드펌킨"
이라고 넣어보았다.
package com.springboot.springbootintro.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HelloController {
@GetMapping("hello")
public String hello(Model model) {
model.addAttribute("nickname", "콜드펌킨");
return "about-me";
}
}
ViewResolver
의 도움으로 resources > template > about-me.html
파일이 화면에 랜더링 된다. 컨트롤러에서 model
에 담아주었던 속성을 출력해 줄 about-me.html
을 Thymeleaf를 이용해 작성해보았다. model에 nickname
이라는 이름으로 값을 담아두었다면, ${nickname}
으로 원하는 위치에 속성 값을 가져올 수 있다. <!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org"> <head>
<title>자기소개</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head>
<body>
<p th:text="'안녕하세요. 저는 ' + ${nickname} + '입니다.'" ></p>
</body>
</html>
컨트롤러에서 리턴된 뷰 네임이 실제 랜더링되는 과정에 대해서 이일민(토비) 님이 더 자세히 설명해 주신 글을 우연히 페이스북에서 발견했는데, 나중에라도 깊게 공부해 볼만한 내용인 것 같아 기록해 두었다.
ViewResolver의 역할은 컨트롤러가 리턴한 뷰 네임으로부터 랜더링을 담당할 View 오브젝트를 준비해 돌려주는 것까지다. 컨트롤러에서 돌려주는 모델을 넘겨 받아 최종 http 응답을 만드는 건 View 오브젝트가 하는 것이고, 이 작업을 진행시키는 건 DispatcherServlet이다. ViewResolver가 화면에 보여줄 최종 html을 생성하는 역할을 다 한다고 오해하면 곤란하다. (토비 이일민 님)
이제 다시 프로젝트를 실행시킨 후 localhost:8080/hello
로 접속해보면, about-me.html
에 작성한 내용과 컨트롤러에서 넘긴 속성 값이 잘 출력되는 것을 확인할 수 있다.
지금까지 개발한 소스를 빌드하고 실행하려면 콘솔창에서 아래 3개 명령어만 차례로 입력하면 된다.
$ ./gradlew build
$ cd build/libs
$ java -jar springboot-intro-0.0.1-SNAPSHOT.jar
$ ./gradlew build
를 실행하면 gradle
이 빌드를 실행하고, 빌드가 완료되면 jar 파일이 담긴build/libs
폴더가 생긴다. 여기서 빌드가 잘 안된다면 build/libs
를 삭제하고 다시 빌드를 수행하도록$ ./gradlew clean build
를 실행한다.
그리고 build/libs
로 이동해서 java -jar springboot-intro-0.0.1-SNAPSHOT.jar
를 실행하면 스프링이 뜨면서 애플리케이션이 동작하는 것을 볼 수 있을 것이다. 실제 운영에 배포할 때도 이[Artifact명]-0.0.1-SNAPSHOT.jar
파일만 복사해서 서버에 넣어주고, java -jar ...
명령어로 실행만 시켜주면 된다.
💡 이 포스트는 김영한 님의 강좌 '스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술' 내용과 강의자료를 바탕으로 제가 이해하고 학습한 내용들을 정리한 글입니다. 혹시 잘못된 내용이 있다면 언제든 댓글로 지적 부탁드립니다.
잘 보다가 갑자기 HelloController 가 등장해서 막혔습니다 ㅠㅠ
뭔가 추가하는 방법 등의 소개가 빠진 거 같네요.