정적 컨텐츠는 파일을 그대로 화면에 띄워주는 것이다. 대신 프로그래밍같은 것은 할 수 없다.
스프링 부트는 정적 컨텐츠 기능을 제공한다. 즉, static 폴더에 있는 html 파일을 그대로 화면에 띄워줄 수 있다.
예를 들어 hello-static.html을 static 폴더 아래 작성하고 localhost:8080/hello-static.html 링크를 들어갈 수 있다.
동작 원리
1. 웹브라우저에서 localhost:8080/hello-static.html 입력
2. 스프링 부트의 내장 톰캣 서버에서 요청을 받아 스프링에게 넘김
3-1. 먼저 controller에서 hello-static 관련 controller가 있는지 확인
3-2. 관련 controller가 없다면 resources 내부의 static/hello-static.html을 찾아 반환해준다.
MVC: Model, View, Controller
코드 작성시 Model, View, Controller의 역할을 구분해 작성해야한다.
View는 화면과 관련된 일만, Controller는 비즈니스 로직이나 서버 뒷단에 관련된 것들민 처리하고 이 과정에서 Model에 화면에 필요한 것들을 담아 화면쪽에 넘겨준다.
Controller
@Controller
public class HelloController {
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam("name") String name, Model model) {
model.addAttribute("name", name);
return "hello-template";
}
}
View
resources/templates/hello-template.html
html
<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'hello ' + ${name}">hello! empty</p>
</body>
</html>
http://localhost:8080/hello-template 링크로 실행하면 다음과 같이 오류가 뜬다.

그 이유는 @RequestParam("name") String name의 RequestParam의 파라미터 중 required()의 default값이 "true"이기 때문에 name을 무조건 넘겨줘야하기 때문이다.

넘겨주는 방식은 쿼리스트링을 이용한다
※ 쿼리스트링
url 주소에 데이터를 파라미터를 통해 넘기는 것
[예시]
url: ~~?name=홍길동
함수: public String helloMvc(String name)인 경우 String name에 '홍길동'이 전달됨
따라서 http://localhost:8080/hello-mvc?name=안뇽과 같은 url을 입력하면 다음과 같이 정상작동하는 것을 볼 수 있다.

※ helloMvc(@RequestParam("name") String name, Model model)에서 @RequestParam("name")부분은 왜 필요할까?
String name만 작성한다면 컴파일 과정에서 변수명이 변경되어 혼동이 올 수 있다. key값이 name이라는 것을 명확하게 표현하기 위해 @RequestParam("name")를 사용한다.
@RequestParam("name")를 사용하지 않는 경우 컴파일 전 후 비교
[전]
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam("name") String name=asdf, Model model) {
model.addAttribute("name", name=asdf);
return "hello-template";
}
[후]
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam("name") String x01=asdf, Model model) {
model.addAttribute("name", x01=asdf);
return "hello-template";
}
동작 원리
1. 웹브라우저에서 localhost:8080/hello-mvc?name=홍길동 입력
2. 스프링 부트의 내장 톰캣 서버에서 요청을 받아 스프링에게 넘김
3. 스프링은 helloController에 매핑된 메서드를 호출해줌. 메서드는 모델에 키는 name, 값은 홍길동 내용을 담고 hello-template를 return해 스프링에게 전달
4. 뷰를 찾아주고 템플릿을 연결시켜주는 일을 하는viewResolver가 templates/hello-template라는 return의 스트링 이름과 똑같은 것을 찾아 Thymeleaf템플릿 엔진에서 처리해달라고 넘김
5. 템플릿 엔진이 렌더링을 해서 변환을 한 html을 웹 브라우저에 반환함
(정적일 때는 변환하지 않았다)
API방식은 @ResponseBody애노테이션을 이용한다.
@ResponseBody 문자 반환 - (실제로 많이 사용하진 않는다)
@GetMapping("hello-string")
@ResponseBody
public String helloString(@RequestParam("name")String name){
return "hello" + name;
}
이는 http의 body부분에 데이터 "hello" + name를 직접 넣어주겠다는 뜻.
템플릿 엔진을 이용한 방식은 뷰(템플릿)를 조작했지만 API를 이용한 방식은 요청한 클라이언트에 html 태그 없이 문자만 그대로 내려간다.

아래 페이지 소스를 봐보면 마크업 언어 없이 정말 데이터만 작성되어 있는 것을 볼 수 있다.

@ResponseBody 객체 반환
@GetMapping("hello-api")
@ResponseBody
public Hello helloApi(@RequestParam("name")String name){
Hello hello = new Hello();
hello.setName(name);
return hello;
}
static class Hello{
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
문자열이 아닌 객체를 반환하면 어떻게 될까?
객체는 json 형식으로 변환되어 전달된다.

동작 원리
1. 웹브라우저에서 localhost:8080/hello-api 입력
2. 스프링 부트의 내장 톰캣 서버에서 요청을 받아 스프링에게 넘김
3. 스프링은 hello-api에 @ResponseBody 애노테이션이 붙어있으므로 API방식으로 동작함
(@ResponseBody이 안붙어있으면 2. MVC와 템플릿 엔진방식으로 viewResolver가 템플릿을 찾아 반환해줌)
4-1. return값이 문자인 경우 - http 응답에 데이터만 넣어 줌
4-2. return값이 객체인 경우 - json방식으로 데이터를 만들어서 http 응답에 반환하는게 디폴트로 설정되어있음
(API방식은 4번의 과정에서 viewResolver대신에 HttpMessageConverter 가 동작한다.
그리고 상황에따라 동작하는 HttpMessageConverter 종류가 다른데 문자이면 StringConverter가, 객체이면 JsonConverter가 동작한다.)
5. 문자 또는 json으로 바꾼 데이터를 나를 요청한 웹브라우저 또는 서버에게 보내줌
@ResponseBody 애노테이션이 있으면 3.API 방식으로 없으면 2. MVC와 템플릿 엔진 방식으로 동작한다.
2. MVC와 템플릿 엔진은 html을 변환하는 방식이다. 이 과정에서 viewResolver가 사용된다.
3.API은 데이터를 바로 내리는 방식이다. 이 과정에서 HttpMessageConverter가 사용된다.