오늘 배운 내용이다.
아직 데이터베이스까지 배우지 않아서, 데이터베이스에 관한 내용은 빠졌다.
MVC란?
소프트웨어 디자인 패턴 중 하나다.
M = Model
V = View
C = Controller
Model
- 데이터와 비즈니스 로직을 담당한다.
- 데이터베이스와 연동하여 데이터를 저장하고 불러오는 등의 작업을 수행한다.
View
- 사용자 인터페이스를 담당한다.
- 사용자가 보는 화면과 버튼, 폼 등을 디자인하고 구현한다.
Controller
- Model과 View 사이의 상호작용을 조정하고 제어한다.
- 사용자의 입력을 받아 Model에 전달하고, Model의 결과를 바탕으로 View를 업데이트 한다.
우리가 Spring MVC를 다루며 Controller 부분을 주로 다룰 것이다.
이것만 보면 잘 이해가 되지 않을 것이다.
Spring MVC란?
Spring Web MVC는 Servlet API를 기반으로 구축된 독창적인 웹 프레임워크로, 처음부터 Spring Framework에 포함되어 왔으며, 정식 명칭인 "Spring Web MVC"는 소스 모듈(spring-webmvc)의 이름에서 따왔으나, "Spring MVC"로 더 일반적으로 알려져 있다. …
Spring MVC는 중앙에 있는 DispatcherServlet이 요청을 처리하기 위한 공유 알고리즘을 제공하는 Front Controller 패턴을 중심으로 설계되어 있으며 이 모델은 유연하고 다양한 워크 플로우를 지원한다.
음... 더 이해 안 될테니 요약한다.
- Spring MVC는 MVC 디자인 패턴을 적용하여 쓰고 있는데, 여기에 DispatcherServlet이 중앙에서 HTTP 요청 (Request, Response)를 효율적으로 처리해준다. DispatcherServlet은 Front Controller 패턴을 중심으로 설계되어있다.
Servlet이란?
Servlet (서블릿)은 자바를 사용하여 웹 페이지를 동적으로 생성하는 서버 측 프로그램 혹은 그 사양을 말한다.
- 사용자가 Client(브라우저)를 통해 서버에 HTTP Request 즉, API를 요청한다.
- 요청을 받은 Servlet Container는 HttpServletRequest, HttpServletResponse 객체를 생성한다.
- HTTP에 담긴 데이터를 약속된 규격에 맞추면서 쉽게 사용하기 위한 객체다
- 설정된 정보를 통해 어떠한 Servlet에 대한 요청인지 찾는다
- 해당 Servlet에서 service 메서드를 호출한 뒤 브라우저의 요청 Method에 따라 doGet 혹은 doPost 등의 메서드를 호출한다.
- 호출한 메서드들의 결과를 그래도 반환하거나 동적 페이지를 생성한 뒤 HttpServletResponse 객체에 응답을 담아서 Client(브라우저)에 반환한다.
- 응답이 완료되면 생성한 HttpServletRequest, HttpServletResponse 객체를 소멸한다.
- 모든 API 요청을 앞서 살펴본 서블릿의 동작 방식에 맞춰 코드를 구현한다면 무수히 많은 Servlet 클래스를 구현해야한다.
- 따라서 Spring은 DispatcherServlet을 사용하여 Front Controller 패턴 방식으로 API 요청을 효율적으로 처리하고 있다.
DispatcherServlet
- Client(브라우저)에서 HTTP Request가 들어오면 DispatcherServlet 객체가 Request를 분석한다
- DispatcherServlet 객체는 분석한 데이터를 토대로 Handler mapping을 통해 Controller를 찾아 Request를 전달한다.
- Handler mapping 에는 API path 와 Controller 메서드가 매칭되어 있다.
- API path 즉, URL을 Controller에 작성하는 방법은 @Controller 애너테이션이 달려있는 클래스를 생성한 뒤 @GetMapping 처럼 요청한 HTTP Method 와 일치하는 애너테이션을 추가한 메서드를 구현한다.
- URL은 @GetMapping("/api/hello") 이처럼 해당 애너테이션의 속성값으로 전달해주면 된다.
- 해당 메서드명을 URL을 매핑하는데 영향을 미치지 않으니 자유롭게 설정해도 된다.
- 이제는 직접 Servlet을 구현하지 않아도 DispatherServlet에 의해 간편하게 HTTP 요청을 처리할 수 있게 됐다.
@Controller public class HtmlController { @GetMapping("/api/hello") public String hello() { return "hello"; // thymeleaf에 의해 resources/templates/hello.html을 반환 } }
- Controller -> DispatherServlet
- 해당 Controller는 요청에 대한 처리를 완료 후 처리에 대한 결과 즉, Moder(데이터)와 View 정보를 전달한다.
- DispatcherServlet -> Client
- ViewResolver를 통해 View에 Model을 적용하여 View를 Client에게 응답으로 전달한다.
동적 페이지
// hello-visit.html
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Hello Spring</title></head>
<body>
<div>
Hello, Spring 동적 웹 페이지!!
</div>
<div>
(방문자 수: <span th:text="${visits}"></span>) // View - 동적 HTML 파일
</div>
</body>
</html>
private static long visitCount = 0; // View에 적용할 정보 -> Model
...
@GetMapping("/html/dynamic")
public String htmlDynamic(Model model) {
visitCount++;
model.addAttribute("visits", visitCount);
return "hello-visit"; // View name
}
여기서 Model (데이터)는 visitCount
View는 (방문자 수: <span th:text="${visits}"></span>)
더 정확히 말하면 View는 hello-visit.html이다. 안에 동적으로 변하는 코드가 들어있기 때문이다
Spring에서는 Model 객체를 제공해주는데 이를 사용하면 된다.
addAttribute("Attributename" , field) 를 쓰는 메소드인데
대충 동적 웹 페이지에 "$(Attributename)" 이 있으면 거기에 field를 넣는다는 소리다.
- 동적 페이지 처리 과정
- Client 의 요청을 Controller에서 Model 로 처리한다.
- DB 조회가 필요하다면 DB 작업 후 처리한 데이터를 Model에 저장한다.
- Template engine(Thymeleaf) 에게 View, Model 전달한다.
- View: 동적 HTML 파일
- Model: View 에 적용할 정보들
- Template engine
- View에 Model을 적용 → 동적 웹페이지 생성
- 예) 로그인 성공 시, "로그인된 사용자의 Nickname"을 페이지에 추가
- Template engine 종류: 타임리프(Thymeleaf), Groovy, FreeMarker, Jade, JSP 등
- View에 Model을 적용 → 동적 웹페이지 생성
- Client(브라우저)에게 View(동적 웹 페이지, HTML)를 전달 해준다.
이해가 되고 난 후 보니 간단하지만 이해 되는 데에 시간이 꽤 걸렸다.
이 사진을 참고하면서 위의 동적 페이지 처리과정을 보면 Controller의 역할이 뭐고 Model은 어떻게 되고
View에 Model을 어떻게 적용시키는지 이해가 될 것이다.
'TIL' 카테고리의 다른 글
TIL 2023-11-03 다형성 업 캐스팅 다운 캐스팅 참조 변수 완벽 이해 (0) | 2023.11.03 |
---|---|
TIL 2023-11-02 Path Variable, Request Param, Model Attribute, Request Body (0) | 2023.11.02 |
TIL 2023-10-31 Spring과 SpringBoot (0) | 2023.10.31 |
TIL 2023-10-30 클래스간의 관계 결정하기 (0) | 2023.10.30 |
TIL 2023-10-27 배열 선언 시 List와 ArrayList (0) | 2023.10.27 |