화면을 보여주는 세가지 방법
- 정적 컨텐츠 - html 파일을 그대로 보여주는 방법
- MVC와 템플릿 엔진 - 백엔드에서 코딩을 통해 html을 동적으로 바꾸는 방법 / 컨트롤러나 템플릿 엔진을 사용함
- API - 다른 데이터 포맷(ex. json)으로 클라이언트에게 데이터를 직접 전달하는 방법
정적 컨텐츠
스프링 부트는 기본적으로 resource 폴더 안에 static 폴더를 가지고 있으며 (= resource/static)
이 폴더에서 정적 컨텐츠(html 등)을 찾아 사용한다.
정적이지 않은 html은 resource/templates 폴더에 저장된다.
cf. 스프링 부트가 제공하는 Welcome Page 기능
스프링은 resources/static/index.html 파일을 찾아 Welcome page (첫 화면)으로 만들어준다.
단, 컨트롤러가 우선순위를 갖으므로, 해당되는 컨트롤러가 없을 때 적용된다.
정적 컨텐츠 작동 원리
URL : localhosl:8080/hello-static.html 을 입력하는 상황
웹 브라우저가 내장 톰캣 서버에 URL을 전달한다.
먼저 hello-static 관련된 컨트롤러가 있는지 파악하고 (-> 컨트롤러가 우선순위를 가짐)
없으면 resource 안에 static 폴더에 hello-static.html 파일이 있는지 파악한다.
MVC와 템플릿 엔진
- Model : 데이터를 담는 그릇 (ex. model.addAttribute(”key”, value) )
- View : 사용자 인터페이스 (화면)
- Controller : 데이터와 사용자의 매개체
세가지로 역할을 나눈 이유 : 비지니스 로직과 화면을 나누어 집중하기 위해
MVC와 템플릿 엔진 동작 원리
URL : localhost:8080/hello-mvc?name=nys를 URL로 입력하는 상황
@Controller
public class HelloController {
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam("name") String name, Model model) {
model.addAttribute("name", name);
return "hello-template";
}
}
>> hello! empty가 화면에 출력된다.
동작 순서
ⓞ 웹 브라우저에서 스트링 부트의 내장 톰캣 서버에 URL을 전달
① 톰켓 서버가 스프링 컨테이너에 URL전달
② 스프링 컨테이너가 Controller에서 @GetMapping(”hello-mvc”) 으로 매핑된 메소드 호출
③ viewResolver가 메소드에서 return 된 string에 해당하는 html 파일을 resources/template 폴더에서 찾고, 모델을 전달. 이때 model.addAttribute(”name”, name);가 같이 전달됨
④ thymeleaf 을 통해 모델에 담긴 데이터가 html에 반영됨 ex. <p th:text="'hello ' + ${name}">hello! empty</p> ⇒ hello nys
API
데이터의 통신(http)은 body 부분이 있는데 body 부분에 직접 데이터를 넣는 방식
MVC 방식은 model을 통해 데이터를 주고 받았는데, API 방법에서는 그런 것 없이 바로 들어간다.
API - String
@Controller
public class HelloController {
@GetMapping("hello-string")
@ResponseBody // response의 body부분에 직접 넣겠다는 의미
public String helloString(@RequestParam("name") String name) { // model이 없다
return "hello " + name;
}
}
이렇게 http에 직접 데이터를 주면 view resolver가 사용되지 않는다.
뷰 리졸버는 Mapping된 함수가 return하는 string에 해당하는 {return값}.html을 찾는 역할을 한다.
하지만 http에 직접 데이터를 주면, 이를 그대로 화면에 내보내므로 html을 쓸 일이 없다.
따라서, html을 찾는 역할을 수행하는 view resolver를 사용할 필요가 없는 것이다.
API - json
// URL : localhost:8080/hello-api?name=yonso
@Controller
public class HelloController{
@GetMapping("hello-api")
@ResponseBody
public Hello helloApir(@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;
}
}
}
@ResponseBody를 선언한 함수에서 리턴 값으로 객체를 리턴하면,
객체는 json으로 변환되어 http의 body로 넘어간다.
json은 key와 value로 이루어진 데이터 집합으로, 위 예시에서는
객체의 변수명이 key, 변수에 대입되는 값이 value가 된다. ⇒ { “name” : “yonso” }
cf. json 예시
{ "name": "식빵", "family": "웰시코기", "age": 1, "weight": 2.14 }
이때도 ‘html을 찾는 것’이 아니기 때문에 view resolver는 작동하지 않는다.
대신, 객체를 json 형태로 바꿔주기 HttpMessageConverter가 동작한다.
API 동작 원리
사용자가 URL을 통해 브라우저에 입력하고,
브라우저는 내장 톰캣 서버에 전달하고,
톰캣 서버는 스프링 컨테이너에 이를 전달하여
Controller가 매핑된 함수를 실행하는 것까지는 동일하다.
하지만, 매핑된 함수에 @ResponseBody 어노테이션이 작성되어있으므로,
return하는 객체를 json으로 바꾸기 위해 HttpMessageConverter가 작동한다.
Summary
- 페이지를 띄우는 방법은 3가지가 있다. [정적 / MVC / API]
- 이 중 MVC와 API 방법이 가장 많이 사용된다.
- MVC - 사용자가 URL을 입력하면, controller가 get방식으로 URL에 해당하는 함수를 호출하고, 함수 안에서 model에 값을 집어넣고, model을 통해 데이터를 view에 전달하여 사용자가 view를 볼 수 있게 한다.
- API - 컨트롤러 안의 함수에서 @ResponseBody를 사용하고, 객체를 리턴하면 객체는 json으로 변환되어 http의 body에 직접 전달된다.
- MVC 방법에서는 View Resolver가, API 방법에서는 HttpMessageConverter가 작동한다.
질문
Q. 그런데 왜 바디 부분에 json을 넣는 방법을 API라고 하셨는지는 아직 이해가 되지 않는다..
API란, Application Programing Interface의 약자로,으로 설명할 수 있다.
- 운영체제와 응용 프로그램 사이의 통신에 사용되는 언어나 메시지 형식
- 구현방식을 알지 못하는 서비스와 통신할 수 있게 해줌 (like 가게 직원)
- 웹기반 데이터 반환 시스템
이라는데 jso 전달 방식이 왜 API 방식이 되는거지?
Q. 뷰 리졸버는 어떻게 동적파일인걸 알고 resources/template 폴더를 뒤질 생각을 하지?
왜 resources/static은 안뒤지는거지?
그냥 컨트롤러로 매핑되는건 다 resources/template 폴더에 저장해야 하는건가?
컨트롤러랑 템플릿은 반드시 함께 쓰이는건가?
기타
cf. API - String에서 string을 http body에 넣기 위해서 StringHttpMessageConverter가 작동하긴 하지만,
String을 직접 넣는 방식은 사장되었으므로 잊어버려도 됨.
'JAVA' 카테고리의 다른 글
[WIL] 5/08~5/14 컬렉션 프레임 워크 (0) | 2023.05.14 |
---|---|
[JAVA] 람다식, Stream, Optional (0) | 2023.05.11 |
스프링 빈과 자동 의존관계 설정 (0) | 2023.04.03 |
[스프링 입문] 회원관리 예제 - 도메인, 레포지토리, 서비스 (0) | 2023.03.14 |
BufferedReader, BufferedWriter (0) | 2022.10.25 |