요약
[정적 컨텐츠 = 그냥 파일을 그대로 보여준다.]
HTML 파일을 그대로 웹에 뿌려주는 것이다.
정적 컨텐츠는 src/main/resources/static 하위에 넣는다.

1) 사용자가 localhost:8080/hello-static.html 을 요청하면 내장 톰켓 서버가 요청을 받는다.
2) 내장 톰켓 서버는 "hello-static.html 요청이 왔대!" 하고 던지고 스프링 부트는 요청을 받는다.
3) 스프링 부트는 먼저 hello-static 관련 컨트롤러를 찾아본다.
4) 만약 없으면 resources/static/hello-static.html 을 찾는다. -> 있으니까 hello-static.html을 사용자에게 반환해준다.
[MVC와 템플릿 엔진 = View와 Model, Controller을 활용하여 동적으로 HTML을 보여준다.]
MVC/템플릿 엔진을 활용하여 뿌려줄 동적 페이지는 src/main/resources/templates 하위에 넣는다.
MVC : Model, View, Controller
만약 View에 모든 코드를 다 짠다면? 코드가 100만줄이라면? 유지보수가 힘들어진다. -> 분리하여 개발
- View : 화면을 뿌려주는 역할
- Model : 데이터를 저장하고 옮겨주는 역할
- Controller : 엔드 포인트를 관리하는 역할

1) 사용자가 localhost:8080/hello-mvc?name=hi 을 요청하면 내장 톰켓 서버가 요청을 받는다.
2) 내장 톰켓 서버는 "hello-static.html 요청이 왔대!" 하고 던지고 스프링 부트는 요청을 받는다.
3) 스프링 부트는 먼저 컨트롤러에서 hello-mvc와 매핑되어 있는 것을 찾아본다. -> 있으면 model에 담긴 변수들과 return 값인 hello-template을 viewResolver에게 넘겨준다.
@Controller
public class helloController {
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam("name") String name, Model model) {
model.addAttribute("name", name);
return "hello-template";
}
}
4) viewResolver은 "받은 정보들에 맞는 템플릿 찾아서 던져주는 역할" 이다. 이전에 받은 리턴값인 'hello-template' 을 참고해서 templates/hello-template.html 을 찾고 그 HTML 파일을 변환을 한다. ( ${name} 부분 = 키 값이 name 이고 value 값이 hi 이므로 ${name} 부분은 hi로 변환이 된다.)
<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'hello ' + ${name}">hello! empty</p>
</body>
</html>
5) 변환된 HTML 파일을 웹 브라우저에 넘겨준다. (클라이언트에게 보여준다.)
[API = 데이터(객체)를 HTTP BODY에 반환/응답(response) 해준다.]
데이터 전송에 활용한다.
@ResponseBody 를 사용한다. -> viewResolver을 사용하지 않는다.
대신 HTTP의 BODY에 문자 내용을 직접 반환한다. (HTML <body> 태그 안을 이야기 하는 것이 아니다.)
객체를 반환하면 객체가 JSON(default) 형태로 변환된다.
=> 서버끼리 데이터를 주고 받거나, 클라이언트와 서버 사이의 데이터 전송에 활용한다. (서버에서는 API를 만들고 Vue.js에서는 API로 만든 데이터를 axios로 받아 사용)

1) 사용자가 localhost:8080/hello-api?name=hi 을 요청하면 내장 톰켓 서버가 요청을 받는다.
2) 내장 톰켓 서버는 "hello-static.html 요청이 왔대!" 하고 던지고 스프링 부트는 요청을 받는다.
3) 스프링 부트는 먼저 컨트롤러에서 hello-api와 매핑되어 있는 것을 찾아본다. -> 있으면 model에 담긴 변수들과 return 값인 hello을 HttpMessageConverter에게 넘겨준다. (@responseBody 어노테이션이 있으므로 viewResolver 에게 넘기지 않고, HttpMessageConverter에게 넘겨준다.)
4-1) HttpMessageConverter 이 받은 리턴값이 문자인 경우 그냥 HTTP BODY에 넣고 클라이언트에게 던져준다. (StringConverter)
4-2) HttpMessageConverter 이 받은 리턴값이 객체인 경우 객체의 값을 JSON 방식으로 데이터를 만들어서 HTTP BODY에 넣고 요청한 곳에 반환한다.(JsonConverter)
참고) 객체를 JSON으로 바꿔주는 라이브러리 = Jackson(스프링 default), gson (구글에서 만들었음)
정적 컨텐츠 실습

<html>
<head>
<title>static content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
정적 컨텐츠 띄우기
</body>
</html>
1. src/main/resources/static 하위에 띄우고 싶은 html 코드를 작성한다.
2. http://localhost:8080/hello-static.html 에 접속하여 결과를 확인한다.
MVC와 템플릿 엔진 실습
1. src/main/java/hello.hellospring/controller 하위에 helloController.java 을 생성한다.

@Controller
public class helloController {
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam("name") String name, Model model) {
model.addAttribute("name", name);
return "hello-template";
}
}
2. src/main/resources/templates 하위에 hello-template.html 을 생성한다.

<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'hello ' + ${name}">hello! empty</p>
</body>
</html>
3. http://localhost:8080/hello-mvc?name=안녕 으로 접속한다.
@Controller은 Controller 사용 시 붙여주어야 하는 어노테이션이다.
@GetMapping은 Get 요청 시 작동한다. 매개변수에 있는 "hello-mvc"는 hello-mvc 주소에 받았을 때 아래 함수가 실행된다는 의미이다.
- Ex) http://localhost:8080/hello-mvc 로 요청한 경우 아래의 helloMvc 메서드가 호출된다.
@RequestParam("name") 은 요청 받는 주소에서 name의 파라미터 값을 받는다는 것이다.
- Ex) http://localhost:8080/hello-mvc?name=hihi 로 요청한 경우 name 변수에는 "hihi" 가 들어간다.
helloMvc 메서드의 2번째 매개변수의 값 model은 매핑된 html에 동적인 변수를 전달해주는 것이다.
- Ex) http://localhost:8080/hello-mvc?name=hihi 로 요청한 경우 name 변수에는 "hihi"가 들어갔었다. 그러면 model.addAttribute("name", "hihi"); 이다. 매핑된 resources/hello-template.html 에서 ${name} 에 "hihi" 가 매핑된다.
return "hello-template" 은 resources/hello-template.html 과 연결되어 웹 페이지를 띄워주는 것이다.
API 실습
1. Controller에 "hello-api" 엔드포인트를 추가해준다.
@GetMapping("hello-api")
@ResponseBody
public Hello helloApi(@RequestParam("name") String name) {
Hello hello = new Hello();
hello.setName(name);
return hello;
}
static class Hello {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2. http://localhost:8080/hello-api 으로 접속한다.

참고 자료
인프런 김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술_섹션 3.스프링 웹 개발 기초 를 참고하였습니다.