웹 개발에는 세 가지 방식이 있다.
- 정적 컨텐츠 : 서버에서 하는 거 없이 html 파일 그대로 웹브라우저로 내려준다.
- mvc & 템플릿 엔진 : JSP, PHP와 같이 html을 그냥 주는 것이 아니라, 서버에서 프로그래밍한 후 html을 동적으로 바꿔서 내려준다.
- API : 요즘은 json이라는 데이터 구조 포맷으로 클라이언트한테 데이터를 전달해준다.
1. 정적 컨텐츠
- 스프링 부트는 정적 컨텐츠 기능을 제공한다(링크)
- 원하는 파일(html)을 넣으면 정적 파일 그대로 반환이 된다. 그 대신 이 파일을 프로그래밍할 수 없다.
- 웹브라우저에서 localhost:8080/hello-static.html을 치면 내장 톰켓 서버가 요청을 받고
- 이런 요청이 왔대 하고 스프링에게 넘긴다. 근데 스프링은 먼저 hello-static 관련 컨트롤러가 있는지 찾아본다(컨트롤러가 우선순위에 있다는 의미) (현재는 없다.)
- 스프링부트는 resources 안에서 static/hello-static.html을 찾는다. 여기서 있으니까
- 웹 브라우저에게 넘겨준다.
2. MVC와 템플릿 엔진
- MVC : Model, View, Controller
- 왜 이런 스타일로 많이 할까?
- 역할 분리를 위해 !!
- 요즘은 Controller와 View를 쪼개는 것이 기본이다.
- View는 화면과 관련된 일만. 비즈니스 로직과 서버 뒷단, 내부적인 로직에 관련된 건 Controller에서 처리하고 Model에 화면에서 필요한 것들을 담아서 넘겨주는 패턴을 많이 사용한다.
타임리프 템플릿의 장점 : html을 그대로 쓰고 그 파일을 서버 없이 그대로 열어봐도 껍데기를 볼 수 있다.
<p th:text="'hello ' + ${name}">hello! empty</p>
템플릿으로 동작을 하면 hello! empty
가 th:text="'hello ' + ${name}"
으로 치환이 된다.
* hello! empty
처럼 넣어놓는 이유는 서버 없이 그냥 html을 볼 때 (html을 markup 해주시는 분들) 값을 적어놓고 볼 수 있으려고!
- 웹브라우저에서 localhost:8080/hello-mvc를 넘기면 스프링 부트 띄울 때 같이 띄우는 내장 톰켓 서버로 넘어간다.
- 내장 톰켓 서버는 스프링한테 hello-mvc을 넘긴다.
- 그럼 스프링은 helloController에 어떤 메서드가 매핑이 되어있네 하고 해당 메서드를 호출해준다. hello-template을 반환해주고 model에 키는 name, 값은 spring을 스프링에 넘긴다.
- viewResolver(화면과 관련된 해결자. 뷰를 찾아주고 템플릿 엔진과 연결시켜줌) 동작한다. templates 폴더에서 return 값과 똑같은 애(hello-template)를 찾아서 타임리프 템플릿 엔진에게 처리해달라고 넘긴다.
- 템플릿 엔진이 렌더링을 해서 변환을 한 html을 웹브라우저에 넘겨준다.
3. API
- 위의 MVC & 템플릿 엔진은 html로 데이터를 내리지만(View 템플릿 조작), API 방식은 뷰가 없다. 데이터(문자 자체)를 바로 내린다.
- 따라서 소스보기 하면 html태그 없이 문자만 나온다.
- 객체를 반환하면 객체가 JSON으로 변환된다. (이것 때문에 api방식 많이 쓴다.)
- XML 방식은 무겁고 html을 열고 닫고 두 번 써야 하는데, JSON은 키:값 바로 나오니 심플하다.
- 스프링도 JSON으로 반환하는 것을 기본으로 되어있다. (XML 하고 싶으면 할 수 있음)
- localhost:8080/hello-api를 치면 내장 톰켓 서버에서 hello-api이 왔다고 스프링에 넘겨준다.
- 스프링은 hello-api가 있네 ? 그런데 @ResponseBody라는 어노테이션이 붙어있으니 http응답에 그대로 이 데이터를 넘겨야겠구나 라고 동작한다. (안 붙어있으면 위 템플릿처럼 viewResolver에게 넘긴다.)
- return 값이 (여기에선) 객체이다. 객체가 오면 스프링은 (기본 디폴트 방식) JSON 방식으로 데이터를 만들어서 http 응답에 반환한다.
- 이 객체를 보고 몇 가지 조건을 보는데, 먼저 HttpMessageConverter가 동작한다.
- 들어온 게 단순 문자열이면 StringConverter가 동작하고
- 객체이면 JsonConverter가 동작하는데 JSON스타일로 바꾼다.
- JSON을 요청한 웹브라우저(또는 서버)에게 보내준다.
- @ResponseBody
- HTTP의 BODY에 문자 내용을 직접 반환
- HTTP에서 BODY부분에 이 데이터를 직접 넣겠다는 의미. (응답 바디 부분에 return내용 직접 넣어주겠다는 의미이다.) (html body tag 아님)
- viewResolver 대신에 HttpMessageConverter 가 동작
- 기본 문자처리: StringHttpMessageConverter
- 기본 객체 처리: MappingJackson2HttpMessageConverter
- byte 처리 등등 기타 여러 HttpMessageConverter가 기본으로 등록되어 있음
- * 깊이 있게 공부하면 이걸 바꿀 수 있는데,, 실무에서 그냥 쓴다 거의 손 안 댄다.
- HTTP의 BODY에 문자 내용을 직접 반환
- 참고: 클라이언트의 HTTP Accept 해더와 서버의 컨트롤러 반환 타입 정보 둘을 조합해서 HttpMessageConverter 가 선택된다.
- http 스펙에 보면 이런 포맷으로 받고 싶어 ~ 하는 http accpet 헤더가 있다. 여기서 json이라고 요청 오면 json으로 받고, 아무것도 안보내면(다 받을 수 있어) 스프링이 알아서 있는 걸로 보낸다. 근데 어떤 방식으로 받아야 해!라고 요청하면 해당 MessageConverter가 동작한다.
* getter & setter
static class Hello {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- getter setter을 사용하면 name은 private이라서 외부에서 바로 못 꺼낸다. 그래서 라이브러리에서 쓰거나 우리가 쓸 때도 get set 메서드를 통해 접근을 하게 된다.(getName, setName은 public으로 연다.)
- 이것을 자바 빈 표준 방식이라고 한다. 또는 property접근 방식이라고도 한다.
참조
이 게시물은 인프런 > 김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술의 강의를 토대로 작성한 게시물입니다.
'Web > Spring' 카테고리의 다른 글
스프링 빈과 의존관계 / 웹 MVC 개발 (0) | 2021.07.25 |
---|---|
회원 관리 예제 - 백엔드 개발 (0) | 2021.07.25 |
스프링 프로젝트 환경설정 (0) | 2021.07.20 |
Application Scope (0) | 2021.06.24 |
Session Scope (0) | 2021.06.24 |