MVC
- Model-View-Controller의 약자
- Model : View가 렌더링하는데 필요한 데이터. ex - 사용자가 요청한 상품 목록이나, 주문 내역
- View : 웹 애플리케이션에서 View는 실제로 보이는 부분이며, 모델을 사용해 렌더링을 합니다. 뷰는 JSP, JSF, PDF, XML등으로 결과를 표현
- Controller : 사용자의 액션에 응답하는 컴포넌트. 컨트롤러는 Model을 업데이트하고, 다른 액션을 수행.
MVC Model
Model 1 아키텍처
브라우저가 요청하면 해당 요청을 JSP가 받음 -> 그렇기에 요청만큼 JSP 페이지가 필요함
JSP는 JAVA로 만든 클래스인 Java Bean(DAO클래스 등)을 이용해 DB를 사용
그 결과를 화면에 출력.
단점 - JSP 자체에 Java와 HTML이 섞여 있어 유지보수가 어려움
이를 해결하기 위해 Model 2를 사용
Model 2 아키텍처
브라우저의 요청을 JSP가 아닌 Servlet이 받음
Servlet이 JAVA Bean을 이용해서 DB에서 데이터를 꺼내와,
그 결과를 JSP를 통해서 화면에 보여줌
여기서 Servlet은 요청과 데이터를 처리하는 컨트롤러의 역할을 수행
JSP는 모델의 결과를 보여주는 View 역할
Model 2 발전 형태
브라우저(클라이언트)의 요청을 Front Controller라는 Servlet 클래스가 다 받음
이 Servlet은 딱 하나만 존재하여 모든 요청을 다 받기만 하지 실제 일을 처리하지 않음
일은 Controller 클래스에게 위임
이런 클래스를 가리켜 Handler 클래스라고 함
이렇게 해서 url마다 하나의 클래스에서 처리할 수 있도록 함
Controller는 Java Bean 등을 이용해 만든 결과를 Model에 담아 Front Controller에 보내면,
Front Controller는 알맞은 View에게 Model을 전달하여 그 결과를 출력
모델 2의 발전되 형태는 Spring의 Web 모듈에 구현되어 있어,
Web 모듈을 보통 Spring MVC라고 함
Spring MVC를 구성하는 컴포넌트들과 동작 순서
파란색 중 Database를 제외한 부분들은 모두 Spring MVC가 제공해줌
보라색은 개발자가 만들어야함
녹색은 Spring이 제공해주지만 개발자가 만들어야 하는 부분도 있음
- 클라이언트 요청
- Dispatcher Servlet : 클라이언트의 모든 요청을 받음
- Handler Mapping : Dispatcher Servlet이 여기에 그 요청을 처리할 컨트롤러와 메소드가 무엇인지 물어봄
- 그 컨트롤러와 메소드는 어노테이션으로 사람이 직접 정의해두어야 함
- 웹 어플리케이션이 실행될 때 Handler Mapping 객체들이 생성되면서 그것들을 관리
- Handler Adapter : Dispatcher Servlet이 여기에 결정된 컨트롤러와 해당 메소드를 실행하라고 요청
- Controller가 반환한 view name을 Dispatcher Servlet에 반환
- View Resolver : Dispatcher Servlet이 view name을 적절한 View Resolver를 찾으라고 전달
- View : 결정된 View로 View를 출력
- Handler Mapping : Dispatcher Servlet이 여기에 그 요청을 처리할 컨트롤러와 메소드가 무엇인지 물어봄
0. Dispatcher Servlet 내부 동작 흐름
- 프론트 컨트롤러 (Front Controller)
- 안내 데스크가 관련 부서에 연결을 돌리는 것과 비슷
- 클라이언트의 모든 요청을 받은 후 이를 처리할 핸들러에게 넘기고 핸들러가 처리한 결과를 받아 사용자에게 응답 결과를 보여준다.
- DispathcerServlet은 여러 컴포넌트를 이용해 작업을 처리한다.
1. 요청 선처리 작업 시 사용된 컴포넌트
Spring MVC는 지역화를 지원.
똑같은 사이트여도 사용자에 따라 영어, 한국어로 된 화면을 각각 지원하도록 처리할 수 있음
사용자마다 브라우저에 설정된 언어를 헤더를 통해 받아와서
Locale을 결정할 수 있음. Locale의 값에 따라 언어별로 화면을 보여주게 하는 것
org.springframework.web.servlet.LocaleResolver
- 지역화 정보를 결정해주는 전략 오브젝트이다.
- 디폴트인 AcceptHeaderLocalResolver는 HTTP 헤더의 정보를 보고 지역정보를 설정해준다.
org.springframework.web.context.request.RequestContextHolder
- Locale 값을 저장
- 스레드 로컬 객체
- 일반 빈에서 HttpServletRequest, HttpServletResponse, HttpSession 등을 사용할 수 있도록 한다.
- 요청 받아서 응답할 때까지 Http 관련 메소드를 이용해
- Spring이 관리하는 객체 안에서 사용할 수 있도록 해줌
- 컨트롤러가 가진 메소드 안에서 Request 객체가 필요하면, 인자에다가 HttpServletRequest request 이렇게 선언만 하면 됨
- 해당 객체를 일반 빈에서 사용하게 되면, Web에 종속적이 될 수 있다.
org.springframework.web.servlet.FlashMapManager
- FlashMap 객체를 조회(retrieve) & 저장을 위한 인터페이스
- RedirectAttributes의 addFlashAttribute메소드를 이용해서 값을 저장한다.
- 리다이렉트로 값을 전달할 때 사용
- url 속? 또는 파라미터를 위해 FlashMap을 사용하여 리다이렉트될 때 딱 한 번 값을 유지할 수 있게 함
- 리다이렉트 후 조회를 하면 바로 정보는 삭제된다.
org.springframework.web.multipart.MultipartResolver
- 파일 업로드에는 HttpServletRequest를 쓰지 않음
- 적합한 Request를 사용할 수 있도록 MultipartResolver가 그 멀티 파트를 정해줌
핸들러
- 실체 요청을 처리하고 실행
2. 요청 전달 시 사용된 컴포넌트
org.springframework.web.servlet.HandlerMapping
- HandlerMapping구현체는 어떤 핸들러가 요청을 처리할지에 대한 정보를 알고 있다.
- 디폴트로 설정되는 있는 핸들러매핑은 BeanNameHandlerMapping과 DefaultAnnotationHandlerMapping 2가지가 설정되어 있다.
org.springframework.web.servlet.HandlerExecutionChain
- HandlerMapping에 따라서 결정됨
- HandlerExecutionChain이 발견되지 않으면 페이지가 없다는 의미
- 이 때는 HTTP 404를 전달 (없는 페이지를 요청했을 때 나오는 에러 400번대)
- HandlerExecutionChain 구현체는 실제로 호출된 핸들러에 대한 참조를 가지고 있다.
- 즉, 무엇이 실행되어야 될지 알고 있는 객체
- 핸들러 실행전과 실행후에 수행될 HandlerInterceptor도 참조하고 있다.
org.springframework.web.servlet.HandlerAdapter
- HandlerExecutionChain가 존재해야 HandlerAdapter가 결정될 수 있음
- 결정된 HandlerAdapter가 없다면 이 때는 서버의 잘못
- ServletException 발생
- 실제 핸들러를 실행하는 역할을 담당한다.
- 핸들러 어댑터는 선택된 핸들러를 실행하는 방법과 응답을 ModelAndView로 변화하는 방법에 대해 알고 있다.
- 디폴트로 설정되어 있는 핸들러어댑터는 HttpRequestHandlerAdapter, SimpleControllerHandlerAdapter, AnnotationMethodHanlderAdapter 3가지이다.
- @RequestMapping과 @Controller 어노테이션을 통해 정의되는 컨트롤러의 경우 DefaultAnnotationHandlerMapping에 의해 핸들러가 결정되고, 그에 대응되는 AnnotationMethodHandlerAdapter에 의해 호출이 일어난다.
3. 요청 처리 시 사용된 컴포넌트
org.springframework.web.servlet.ModelAndView
- ModelAndView는 Controller의 처리 결과를 보여줄 view와
- view에서 사용할 값을 전달하는 클래스
- 사용 가능한 인터셉트가 존재하면 인터셉트의 preHandler를 호출해서 요청 처리 후 핸들러 실행
- 인터셉트 : 뭔가 처리하기 전에 한 번 거쳐지나가는 것
- 이 때, 핸들러가 리턴하는 것은 ModelAndView 객체
- 만약 이 객체가 View를 가지고 있지 않다면, RequestToViewNameTranslator가 동작
- 가지고 있다면, 인터셉트의 postHandler를 호출하여 요청 처리 후 뷰 렌더링해서 결과를보여줌
org.springframework.web.servlet.RequestToViewNameTranslator
- 컨트롤러에서 뷰 이름이나 뷰 오브젝트를 제공해주지 않았을 경우
- URL과 같은 요청정보를 참고해서 자동으로 뷰 이름을 생성해주는 전략 오브젝트이다.
- 디폴트는 DefaultRequestToViewNameTranslator이다.
4. 예외 처리 시 사용된 컴포넌트
org.springframework.web.servlet.handlerexceptionresolver
- 기본적으로 DispatcherServlet이 DefaultHandlerExceptionResolver를 등록한다.
- HandlerExceptionResolver는 예외가 던져졌을 때 어떤 핸들러를 실행할 것인지에 대한 정보를 제공한다.
- ModelAndView가 있다면 요청 처리를 다시 시작
5. 뷰 렌더링 시 사용된 컴포넌트
org.springframework.web.servlet.ViewResolver
- 컨트롤러가 리턴한 뷰 이름을 참고해서 적절한 뷰 오브젝트를 찾아주는 로직을 가진 전략 오프젝트이다.
- ViewResolver의 구현체를 찾지 못했다면, (만약 뷰가 String이라면), ServletException 발생
- 구현체를 찾았다면 렌더링 하고 요청 처리를 계속함
- 뷰의 종류에 따라 적절한 ViewResolver를 추가로 설정해줄 수 있다.
6. 요청 처리 종료 시 사용된 컴포넌트
HandlerExecutionChain이 존재하면
-> 인터셉트의 afterCompletion 실행 -> RequestHandleEvent 발생 -> 요청 처리
존재하지 않는다면
-> RequestHandleEvent 발생 -> 요청 처리
'Web > Java+Spring' 카테고리의 다른 글
Spring MVC - Controller 작성 실습 2 (0) | 2021.06.07 |
---|---|
Spring MVC - Controller 작성 실습 1 (0) | 2021.06.07 |
Spring JDBC - DTO/DAO (0) | 2021.06.02 |
Spring JDBC (0) | 2021.06.02 |
JAVA Config (0) | 2021.06.02 |