서블릿(Servlet)이란?
-> 웹 클라이언트에게 요청을 받고(브라우저), 그에 대한 응답을 생성하여 클라이언트에게 반환하는 역할
클라이언트의 요청을 처리하도록 특정 규약에 맞춰 Java코드로 작성하는 클래스 파일이다.
아파치 톰캣은 이러한 서블릿들이 웹 애플리케이션으로 실행될 수 있도록 해주는 서블릿 컨테이너 중 하나다.
스프링 MVC 내부에는 서블릿을 기반으로 웹 애플리케이션이 동작하며, 스프링 부트는 기본적으로 아파치 톰캣이 내장되어 있다.
□ MVC 패턴이란?
애플리케이션을 개발할 때 사용하는 패턴
개발 영역을 Model, View, Controller로 구분하여
각 역할에 맞게 코드를 작성하는 개발방식
∴ UI 영역과 도메인(비즈니스 로직) 영역을 분리하여
서로 영향 주지 않으면서 개발과 유지보수 가능해짐
Model : 웹 어플리케이션이 요청을 전달 받으면 요청 사항을 처리하기 위한 작업을 한다.
처리한 작업 결과 데이터를 클라이언트에게 응답으로 돌려주는데,
이때 클라이언트에게 응답으로 돌려주는 작업의 처리 결과 데이터를 Model이라고 한다.
클라이언트의 요청 사항을 구체적으로 처리하는 영역을 서비스 계층(Service layer),
요청 사항을 처리하기 위해 Java코드로 구현한 것을 비즈니스 로직(Business Logic)이라고 한다.
View : Model을 이용해 웹 브라우저와 같은 애플리케이션의 화면에 보이는 리소스를 제공
- HTML 페이지 출력
- XML, JSON 등 특정 형식의 포맷으로 변환
Controller : 클라이언트 요청을 직접적으로 전달 받는 엔드포인트(Endpoint)
Model과 View의 중간에서 상호작용 해주는 역할
클라이언트 ---(요청)--->
비즈니스 로직 ---(처리)--->
Model ---(전달)---> View
구현 난이도는 비교적 쉽지만, 유지보수 복잡
JSP가 컨트롤러와 뷰의 역할을 모두 수행. 비즈니스 & 프레젠테이션 로직이 혼합되어 코드가 복잡하고 유지보수가 어려웠던 MVC1 패턴
확장성과 유지보수성을 크게 향상시키는데 중점
ㄴ> 서블릿이 컨트롤러 역할을, JSP가 뷰를 담당하여 역할을 분리, MVC1의 문제를 해결한 MVC2 패턴
ㄴ> MVC2 패턴을 더 발전시켜 장점을 극대화하고, 다양한 기능을 추가하여 웹 프레임워크 제공하는 Spring MVC !
■ Spring MVC
□ 발전 과정
1. @RequestMapping 사용
초기 Spring MVC에서는 @RequestMapping 어노테이션을 사용해 URL요청을 컨트롤러 메서드와 매핑했다.
(@RequestMapping 어노테이션은 HTTP메서드 (GET, POST, PUT, DELETE) 관계없이 모든 요청을 처리할 수 있었음)
2. 클래스 단위 컨트롤러 통합
spring 3.0부터는 @RequestMapping 클래스 레벨에 적용할 수 있게 되어, 클래스 단위로 컨트롤러를 통합할 수 있게 되었다.
(URL접두사를 클래스 레벨에서 지정하고, 메서드 레벨에서 세부 경로를 지정할 수 있게 되어 코드가 더 간결하고 유지보수가 쉬워졌다.)
3. @GetMapping, @PostMapping, @RequestParam & Model 도입
spring 4.3부터는 @GetMapping, @PostMapping, @RequestParam등 다양한 어노테이션이 도입되어 HTTP별 매핑과 요청 매개변수 바인딩을 명확히 함. model 객체 도입으로 뷰에 데이터 전달이 용이해짐
□ 주요 기능
DispatcherServlet을 중심으로 모든 요청을 처리하며, 다양한 구성 요소들이 협력하여 웹 요청을 처리한다.
-> web.xml이나 org.springframework.web.WebApplicationInitializer 인터페이스를 구현하여 Front Controller로 설정한다.
스프링 MVC는 클라이언트의 요청을 편리하게 처리할 수 있도록 다양한 기능을 제공한다.
1. 요청 매핑 기능
@RequestMapping : URL 요청을 메서드에 매핑
@GetMapping, @PostMapping, @PutMapping, @DeleteMappling : HTTP메서드에 따라 요청을 매핑
@PathVariable : URL 경로에서 변수 값 추출
@RequestParam : 요청 파라미터를 메서드 파라미터에 바인딩
2. 유연한 데이터 바인딩 및 검증
@ModelAttribute : 모델 데이터를 뷰에 전달하거나 폼 데이터를 객체에 바인딩
@Vaild : 스프링의 검증 API를 사용해 폼 데이터 검증
@BindingResult : 검증 결과 확인하고 오류 메시지 처리
3. 다양한 응답 형식 지원
JSP, Thymeleaf, 등 지원
@ResponseBody : 컨트롤러 메서드가 반환하는 객체를 HTTP 응답 본문으로 변환
4. 세션 및 쿠키 관리
@SessionAttributes : 세션에 모델 데이터 저장
@CookieValue : 쿠키 값을 메서드 파라미터에 바인딩
5. RESTful
@RestController : RESTful 웹 서비스를 쉽게 구현할 수 있도록 지원
@ResponseStatus : HTTP 상태 코드 설정
@RequestBody : HTTP 요청 본문 객체에 바인딩
등의 기능을 제공한다.
□ 구조
- DispatcherSevlet : 모든 요청을 받아서 적절한 컨트롤러로 전달하는 프론트 컨트롤러 역할을 한다.
- Controller : client 요청을 처리하고, 필요한 데이터와 함께 뷰 이름을 반환한다. 각 요청에 따라 비즈니스 로직을 수행하고, 모델 데이터를 준비한다.
- Model : 애플리케이션의 데이터를 나타내며, 비즈니스 로직을 포함한다. 데이터베이스와 상호작용을 주로 담당한다.
- View : 모델 데이터를 사용해 사용자에게 보여줄 결과를 생성한다.
□ 특징과 장점
- 유연한 구조
컴포넌트간 의존성이 적어 각 구성 요소를 독립적으로 교체하고 확장할 수 있다.
- 테스트 용이성
각 구성 요소가 분리되어 있어 단위/통합 테스트를 쉽게 수행할 수 있다.
□ 사용 이유
- 코드 유지보수 용이
코드가 명확히 분리되어 특정 기능에 문제가 발생했을 때, 해당 부분만 수정하면 된다.
예를 들어, ui에 변화가 필요하면 view만 수정하면 되고, 비즈니스 로직 변경은 Model부분만 수정하면 된다.
이런 분리 덕분에 코드 가독성과 유지 보수성이 높아진다.
- 재사용성 증가
각 mvc가 독립적으로 존재하므로, 다른 프로젝트나 모듈에서도 재사용하기 쉽다.
중복 코드가 줄어들고 개발 효율성이 높아진다.
- 동시 개발 가능
팀 내에서 각기 다른 역할을 맡아 동시에 개발할 수 있다.
프론트엔트 개발자는 view를, 백엔드 개발자는 model과 controller를 개발할 수 있다.
역할을 분리하면 개발 속도가 빨라지고, 각자 자신의 영역에 집중할 수 있어 품질이 향상된다.
□ 동작원리
1. 요청 (Request) : 사용자가 URL로 요청 보냄
사용자가 서버에 GET, POST, PUT, DELETE 등의 HTTP 메서드를 사용해 HTTP 요청을 보낼 수 있다.
2. DispatcherServlet : 모든 요청을 받아 적절한 핸들러로 라우팅
모든 HTTP요청은 먼저 DispatcherServlet에 도달한다.
DispatcherServlet은 프론트 컨트롤러로 모든 요청을 중앙에서 처리하고,
적절한 컨트롤러로 라우팅하는 역할을 한다.
3. HandlerMapping : 요청 URL과 일치하는 컨트롤러 찾음
DispatcherServlet은 요청 URL을 기반으로 요청을 처리할 컨트롤러를 찾기 위해
여러 HandlerMapping 구현체 중 하나를 사용한다.
HandlerMapping는 요청 URL과 일치하는 컨트롤러를 찾아 반환한다.
HandlerAdaper : 컨트롤러의 동작 결과인 Model과 View를 반환한다.
DispatcherServlet이 HandlerMapping을 통해 컨트롤러를 찾으면,
해당 컨트롤러를 호출하기 위해 적절한 HandlerAdapter를 선택한다.
DispatcherServlet과 Controller 사이의 어댑터 역할을 한다.
컨트롤러 종류에 따라 다르게 동작할 수 있도록 하며, 실제 컨트롤러 호출 로직을 캡슐화 한다.
4. Controller : 비즈니스 로직을 처리하고 모델 데이터를 준비
HandlerMapping에 의해 결정된 컨트롤러가 호출된다.
컨트롤러는 비즈니스 로직을 수행하고 필요한 데이터를 준비한다.
비즈니스 로직은 서비스 계층과 데이터 액세스 계층을 호출하여 데이터를 처리하고
결과를 Model 객체에 저장한다.
5. Model : 데이터를 포함하고, 뷰에 전달할 준비 완료
컨트롤러가 처리한 데이터의 컨테이너 역할을 한다.
Model 객체는 데이터를 담고 있으며,
이 데이터는 뷰에 전달되어 사용자에게 표시된다.
컨트롤러는 Model 객체에 데이터를 추가하여 뷰에서 사용할 수 있도록 준비한다.
6. ViewResolver : 모델 데이터 바탕으로 적절한 뷰 선택
컨트롤러가 반환한 논리적인 뷰 이름을 실제 뷰 객체로 변환하기 위해 ViewResolver가 사용된다.
ViewResolver는 논리적인 뷰 이름을 기반으로 적절히 뷰를 선택한다.
7. View : 사용자에게 데이터 표시
ViewResolver가 선택한 뷰는 Model 데이터를 사용하여
최종적인 HTML, JSON, XML 등 형식으로 변환해 사용자에게 표시된다.
(JSP, Thymeleaf 등)
8. 응답 (Response) : 최종 결과를 사용자에게 반환
최종적으로 생성된 뷰는 HTTP 응답으로 사용자에게 반환된다.
브라우저는 이 응답을 받아서 사용자에게 표시한다.
이 과정에서 사용자는 요청에 대한 결과를 확인할 수 있다.
∴ 사용자의 요청을 받아, 컨트롤러에서 처리 후, 모델 데이터를 뷰로 전달하여, 사용자에게 응답.
[비유]
Model : 주방, 요리사 (데이터와 로직)
View : 레스토랑 홀, 고객이 보는 메뉴와 음식 (UI)
Controller : 웨이터 (주문 받고, 주방에 전달하고, 음식 갖다줌)
-> 웨이터는 고객의 주문을 받고, 주방에 전달한다.
웨이터는 완성된 음식을 고객에게 전달한다.
고객은 주방의 복잡한 과정을 알 필요 없이 단순히 음식을 받아 맛있게 먹기만 하면 된다 !
- 예외처리 구현 : @ExceptionHandler , @ControllerAdvice, 사용자 정의 등
- DispatcherServlet : 모든 HTTP 요청을 받아 적절한 핸들러로 라우팅하고, 응답을 생성하여 반환하는 역할
- ModelAttribute 용도 : 요청 매개변수를 모델 객체에 바인딩하고, 해당 객체를 뷰에 전달하기 위해 사용
- RESTful 웹 서비스를 위한 Spring MVC 설정 방법 ?
@RestController 어노테이션을 사용, @RequestMapping 또는 @GetMapping, @PostMapping 등의 어노테이션을 사용해 HTTP 메서드에 매핑
직렬화 @ResponseBody : Controller 반환 Java 객체 to JSON ---> HTTP 응답 본문
역직렬화 @RequestBody : HTTP 요청 본문 JSON to Java ---> Controller 매개변수로 전달
'CS' 카테고리의 다른 글
CS)네트워크_대역폭 (1) | 2024.05.22 |
---|---|
CS)네트워크_네트워크 기초 (0) | 2024.05.22 |
CS)Spring_10_빈 라이프 사이클 (0) | 2024.04.25 |
S)Spring_10_스프링 컴포넌트 스캔 Component Scan & DI 자동 주입 (0) | 2024.04.15 |
S)Spring_09_스프링 컨테이너 (2) | 2024.04.10 |