본문 바로가기
  • 개발공부 및 일상적인 내용을 작성하는 블로그 입니다.
Spring basic

스프링 입문 : 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 정적 컨텐츠 및 MVC 와 템플릿 엔진

by 방구석 대학생 2021. 10. 23.

"인프런의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 강의를 듣고 작성한 글 입니다."

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8

 

[무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., 스프링 학습 첫 길잡이! 개발 공부의 길을 잃지 않도록 도와드립니다. 📣 확인해주세

www.inflearn.com

 

* 웹을 개발하는데는 크게 3가지 방법이 있다.

1. 정적 컨텐츠 : 서버에서 별 다른 처리 없이 파일 자체를 웹 브라우저에 내려주는 것

2. MVC 와 템플릿 엔진 : 요즘 가장 많이 하는 방식으로, html 파일을 그냥 주는게 아니라 서버 측에서 프로그래밍을 통해 html 에 동적인 기능을 부여해 줄 수 있는것이 템플릿 엔진의 역할 -> 이를 수행하기 위한 Controller, Model, View 와 같은 3가지 구성요소를 MVC 라고 한다.

 

* 정적 컨텐츠 와의 차이점

정적 컨텐츠의 경우 파일을 그대로 전달해주는 것이지만 MVC 와 템플릿 엔진은 서버에서의 변형을 통해 html 에 동적인 기능을 부여하여 웹 브라우저에 내려주는 방식이라는 것이다.

 

3. API : JSON 과 같은 데이터 구조를 통해 필요한 데이터를 클라이언트 측에 전달해주는 방식

 

정적 컨텐츠 - 스프링 부트는 정적 컨텐츠 기능을 자동으로 제공해준다.

스프링 부트 정적 컨텐츠 관련 내용 링크 : https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/html/spring-bootfeatures.html#boot-features-spring-mvc-static-content

 

웹 프로젝트에서 static 폴더에 hello-static.html 파일을 만들어 놓고 해당 파일을 웹 브라우저에 띄워보자.

- hello-static.html

<!DOCTYPE HTML>
<html>
<head>
<title>static content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
정적 컨텐츠 입니다.
</body>
</html>

접속 URL : http://localhost:8080/hello-static.html

 

위의 경로로 웹 브라우저를 통해 접속해보면 해당하는 파일의 내용이 잘 출력되는 것을 확인할 수 있다.

다만 정적인 컨텐츠이기 때문에 별다른 동적인 기능을 수행하지는 않는다.

말 그대로 파일의 내용 그 자체를 출력해주기만 하는 것이다.

 

* 정적 컨텐츠 동작 원리

1. 웹 브라우저에서 http://localhost:8080/hello-static.html 경로 접속

2. 내장 톰캣 서버에서 요청을 받고 해당 내용을 스프링으로 넘겨준다.

3. 스프링으로 요청이 넘어오면 Controller 쪽에서 hello-static 으로 경로가 매핑된 메소드가 있는지 먼저 찾아본다.

(컨트롤러가 정적 컨텐츠 보다 경로 탐색 우선순위를 먼저 가진다.)

4. Controller 에 URL 이 매핑된 메소드가 존재하지 않을 경우 내부에 있는 static/hello-static.html 파일을 찾는다.

5. 파일이 존재할 경우 웹 브라우저로 반환해준다.

 

 

MVC와 템플릿 엔진

개발을 공부하는데 있어서 관심사를 분리해야 한다는 말이 있듯이 웹 개발을 할 때에는

View 에서는 화면을 그리고 출력해주는 것에 모든 역량을 집중해 줘야 하고, Controller 와 Model 과 관련된 부분은 비즈니스 로직이나 다른 내부적인 처리를 해주는데 집중해야 한다.

서로 다른 분야간 선택과 집중을 위해 원래 하나였던 View - Controller 가 쪼개진 것이다.

(옛날엔 뷰 파일 하나에 (jsp) 비즈니스 로직에서부터 데이터베이스 접근까지 전부 다 있었다.)

 

다음과 같이 코딩해보자.

- helloController.java

// hello-mvc 경로 매핑된 메소드 생성(파라미터 값으로 name 을 받아야 한다.)
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam("name") String name, Model model){
    model.addAttribute("name", name);
    return "hello-template";
}

뷰 파일도 하나 생성해보자.

- hello-template.html

<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'hello ' + ${name}">hello! empty</p>
</body>
</html>

여기서 컨트롤러 측 파라미터에 데이터를 넘겨주는 값 없이 localhost:8080/hello-mvc 와 같이 경로에 접속하게 되면 에러가 발생하게 된다.

 

그렇다면 발생한 에러에 대한 로그를 살펴보자.

MissingServletRequestParameterException: Required request parameter 'name' for method parameter type String is not present

 

위의 로그를 살펴보면 request parameter 로 name 변수가 필요하다는 것을 알 수 있다.

이제 컨트롤러에서 코드를 아래와 같이 변경해보자.

- helloController.java

@GetMapping("hello-mvc")
public String helloMvc(@RequestParam(value = "name", required = false) String name, Model model){
    model.addAttribute("name", name);
    return "hello-template";
}

여기서 @RequestParam 어노테이션의 괄호 내부에 required = false 가 추가된 것을 볼 수 있는데, 이와 같이 설정을 해두면 request parameter 로 필요한 변수 값이 설정되어 있지 않아도 에러 없이 화면이 잘 출력되는 것을 확인할 수 있다.

(localhost:8080/hello-mvc 와 같은 경로로 name 변수 없이 접속해도 에러 없이 접속이 잘 된다.)

원래 required 속성은 기본값(default) 으로 true 가 설정되어 있는데, 이를 false 로 바꿔줌으로써 @RequestParam 을 통해 컨트롤러로 넘어와야 하는 변수가 존재하지 않아도 에러가 발생하는 것을 막아주는 것이다.

 

그렇다면 이번엔 다시 required = false 와 같은 설정 없이 @RequestParam 어노테이션에 들어있는 request parameter 변수에 데이터 값을 제대로 적재하여 화면이 에러없이 잘 출력될 수 있도록 해보자.

-helloController.java

// hello-mvc 경로 매핑된 메소드 생성(파라미터 값으로 name 을 받아야 한다.)
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam("name") String name, Model model){
    model.addAttribute("name", name);
    return "hello-template";
}

접속 URL : localhost:8080/hello-mvc?name=spring!!!

 

위와 같은 경로로 접속 했을 경우 화면이 에러없이 잘 출력되는 것을 확인해 볼 수 있다.

여기서 name 변수에 들어간 spring!!! 값 또한 thymeleaf 템플릿 엔진의 기능으로 인해 그 값이 화면에 잘 출력된다.

 

* MVC 와 템플릿엔진 동작원리

 

1. 위에서 작성한 URL 과 같이 name 변수에 값이 적재되어 컨트롤러로 접속 요청이 넘어간다.

2. hello-mvc 로 경로가 매핑된 메소드를 컨트롤러 내부에서 찾은 후, 해당 메소드가 요구하는 name 변수가 URL 에 존재하는지 확인한다.

3. URL 에 name 변수가 존재한다면 해당 변수의 값을 메소드에 @RequestParam 어노테이션을 통해 선언해둔 변수에 적재해준 후 메소드의 기능을 동작시킨다. (model 에 name 변수의 값이 담기게 된다.)

4. 메소드의 동작을 수행한 이후 뷰 리졸버(viewResolver) 를 통해 다시 return 에 적혀있는 문자열 값을 이름으로 하는 파일을 찾아서 thymeleaf 템플릿 엔진이 처리를 해줄 수 있게끔 넘겨준다.

5. 템플릿 엔진이 랜더링을 통해 변환이(동적인 기능이 수행되고 있으므로 thymeleaf 를 통해 파일의 내용을 변환해 주어야 한다.) 된 후 해당 파일을 웹 브라우저 상에 출력 시켜준다.