csmoon1010의 SW 블로그

Spring MVC (부스트코스) 본문

웹/백엔드

Spring MVC (부스트코스)

csmoon1010 2022. 4. 17. 22:59

1. MVC (Model-View-Controller)

- Model : View가 렌더링하는데 필요한 "데이터" (ex> 상품 목록, 주문 내역 ... )

- View : 실제로 "보이는" 부분, Model을 통해 렌더링 (ex> JSP, JSF, PDF, XML 등)

- Controller : 사용자의 액션에 "응답"하는 컴포넌트, Model을 업데이트하여 다른 액션을 수행

 

1) MVC Model1 아키텍처

MVC Model 1

- Request 만큼 JSP Page가 존재해야 함

- 단점 : JSP Page에 java와 html이 함께 존재해 유지보수의 어려움 有

 

2) MVC Model2 아키텍처

MVC Model2
MVC Model2 발전형태

- 프론트 컨트롤러 : 1개만 존재, 모든 요청을 받기만 하고 실제 일은 컨트롤러(핸들러)에게 위임

- 컨트롤러(핸들러) : 프론트 컨트롤러에게 받은 요청을 Java bean 등을 통해 처리 후, 모델을 통해 프론트 컨트롤러에 결과 전달

- 뷰 템플릿 : 프론트 컨트롤러로 부터 받은 모델을 렌더링하여 클라이언트에게 응답

==> 로직과 뷰를 분리한 형태

==> Spring Web Module : Model2 MVC 패턴을 지원

 

 

2. Spring MVC

1) 기본 동작 흐름

Spring MVC 기본 동작 흐름

① DispatcherServlet : 클라이언트가 보낸 모든 요청을 받음

② HandlerMapping : 어노테이션 등을 통한 설정으로 요청에 맞는 Controller, Method를 알아내어

→ DispatcherServlet에게 전달

③, ④, ⑤ HandlerAdapter : Dispatcher Servlet으로 부터 전달받은 Controller, Method를 실행

→ 결과를 Model에 받아 전달

⑥ ViewResolver : DispatcherServlet으로 부터 전달받은 view name을 가지고 View의 정보 전달

⑦, ⑧ View : DispatcherServlet으로 부터 전달받은 정보를 통해 View 출력

 

 

2) DispatcherServlet

: Front Controller = 클라이언트의 요청을 받아서 넘겨주고, 처리한 결과를 받아 응답결과를 전달

DispatcherServlet의 내부 동작흐름

 

(1) 요청 선처리 작업

- 지역화 : 클라이언트에서 보내는 정보에 따라서 Locale을 결정 (org.springframework.web.servlet.LocaleResolver / ex> 브라우저의 언어)

- RequestContextHandler에 요청 저장 : 요청~응답까지 HttpServletRequset, HttpServletResponse 등을 Spring 관리 객체에서 사용할 수 있도록 저장

(org.springframework.web.context.request.RequestContextHolder / 단, 웹기술에 종속되는 문제점이 있을 수 있음)

- FlashMap 복원 : redirect될 때 URL의 ?, 파라미터 등의 값을 딱 한 번 값을 유지시킴 (org.springframework.web.servlet.FlashMapManager)

- 멀티파트요청&결정 : 다른 형식의 Request가 들어왔을 때, MultipartResolver에게 요청&결정

- Handler 결정과 실행 : 실제 요청을 처리할 Handler를 결정하고 실행
(org.springframework.web.multipart.MultipartResolver)

 

(2) 요청 전달

- HandlerMapping : "어떤 Handler"가 요청을 처리할지에 대한 정보를 알고 있는 컴포넌트

(org.springframework.web.servlet.HandlerMapping)

- HandlerExecutionChain : 실제로 호출된 Handler에 대한 "참조"를 가진 컴포넌트

+ 실행 전, 후에 수행될 HandlerInterceptor에 대한 참조

(org.springframework.web.servlet.HandlerExecutionChain)

- HandlerAdapter : 실제 Handler를 "실행"하는 컴포넌트로, 실행 방법과 응답을 ModelAndView로 변환하는 방법을 알고있음

(org.springframework.web.servlet.HandlerAdapter)

 

(3) 요청 처리

- Interceptor : 필터 역할 / 존재한다면 핸들러 실행없이 Interceptor의 preHandler를 통해 요청 처리 가능

- ModelAndView : Controller의 처리 결과를 보여줄 "View" + View에서 사용할 값을 전달하는 클래스 ("Model")

- RequestToViewNameTranslator : Controller에서 View를 제공하지 않은 경우, 요청정보 (ex> URL)를 참고해서 자동으로 뷰 이름을 생성

 

(4) 예외처리

- HandlerExceptionResolver : 예외가 던져졌을 때 어떤 Handler를 실행할 것이에 대한 정보를 가진 컴포넌트

(org.springframework.web.servlet.handlerexceptionresolver)

 

(5) 뷰 렌더링

- ViewResolver : Controller가 리턴한 View 이름을 참고해서 적절한 View Object를 찾아주는 로직을 가진 전략 컴포넌트

(org.springframework.web.servlet.ViewResolver)

 

(6) 요청 처리 종료

 

 

 

 

3. 실습

1) DispatcherServlet을 FrontController로 설정

(1) 방법

-web.xml 파일에 설정

<init-param> : xml이 아닌, 자바 config class를 이용해 설정
<url-pattern> : 특정 하나의 요청이 아닌 모든 요청을 받기 때문에 / 로 설정

- javax.servlet.ServletContainerInitializer 사용
(서블릿 3.0 스펙 이상에서 web.xml파일을 대신해서 사용 가능)
- org.springframework.web.WebApplicationInitializer 인터페이스를 구현해서 사용
단점 : 처음 웹 어플리케이션의 구동 시간이 오래 소요됨 (구현체를 찾은 뒤 onStartup 메서드를 통해 초기화)

 

 

2) Spring MVC 설정

kr.or.connect.webmvc.config.WebMvcContextConfiguration

: 자바 config를 통해 DispatcherServlet이 읽어들여야될 설정 작성 (=> 설정을 읽어 ApplicationContext 생성)

(1) @Cofiguration : Java Config 파일임을 알려주는 역할

(2) @EnableMVC : 필요한 Bean들을 자동으로 설정해주는 역할
(ex> RequestMappingHandlerMapping, RequestMappingHandlerAdapter, ExceptionHandlerExceptionResolver, MessageConverter 등)
++ 추가로 필요한 설정은 WebMvcConfigurerAdapter를 상속받도록 Java config class를 작성한 후, 메소드를 오버라이딩

(참고)

https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java

 

(3) @ComponentScan : Controller, Service, Repository, Component 어노테이션이 붙은 클래스를 찾아 관리할 수 있게하는 역할
- HandlerMapping : DispatcherServlet을 통해 들어온 요청을 어느 Handler로 전달할지 결정
① DefaultAnnotationHandlerMapping : DispatcherServlet의 default 핸들러 맵핑 객체

RequestMappingHandlerMapping : 좀 더 강력하고 유연한 핸들러 맵핑 객체, 명시적 설정 필요.
==> ApplicationContext에 있는 요청 처리 Bean에서 RequestMapping Annotation을 찾아 HandlerMapping 객체 생성

 

(4) WebMvcConfigurerAdapter

- org.springframework.web.servlet.config.annotation. WebMvcConfigurerAdapter
- @EnableWebMvc를 이용한 기본 설정 외의 설정이 필요한 경우 이 클래스를 상속받아 오버라이딩하여 구현

 

 

3) Controller

: HandlerMapping이 요청에 따라 찾는, 실제로 요청을 처리하는 Handler

(1) @Controller : @ComponentScan에서 Controller임을 알려주는 역할

(2) @RequestMapping : 요청에 대한 맵핑 역할 (어떤 요청을 처리하는 Handler인지를 구분해주는 역할)

- Http 요청과 이를 다루기 위한 Controller의 메소드를 연결

- 사용방법
EX> /users라는 URL로 들어온 요청을 POST 방식으로 처리

@RequestMapping(value="/users", method=RequestMethod.POST)

- 연결 종류에 따른 방법

//1. Http 특정 해더와 연결하는 방법
@RequestMapping(method = RequestMethod.GET, headers = "content-type=application/json")

//2. Http Parameter 와 연결하는 방법
 @RequestMapping(method = RequestMethod.GET, params = "type=raw")

//3. Content-Type Header 와 연결하는 방법
@RequestMapping(method = RequestMethod.GET, consumes = "application/json")

//4. Accept Header 와 연결하는 방법
@RequestMapping(method = RequestMethod.GET, produces = "application/json")

' > 백엔드' 카테고리의 다른 글

Spring JDBC - (부스트코스)  (0) 2021.04.11
Spring Core - (부스트코스)  (0) 2021.04.11
WEB API - (부스트코스)  (0) 2021.04.09
JDBC - (부스트코스)  (0) 2021.04.08
Maven - (부스트코스)  (0) 2021.04.08
Comments