[Java] 자바 스프링(spring) MVC 정리(1)

업데이트:

자바 스프링(spring) MVC 간단 정리

참고자료 : 토비의 스프링 3.1 vol2, 3장 스프링 웹 기술과 스피링 MVC

MVC는 프레젠테이션 계층의 구성요소를 정보를 담은 모델(M), 화면 출력 로직을 담은 뷰(V), 그리고 제어 로직을 담은 컨트롤러(C)로 분리하고 이 세가지 요소가 서로 협력해서 하나의 웹 요청을 처리 하고 응답하는 구조.

프레젠테이션 계층이란? 위키백과에 따른면,

프레젠테이션 계층(presentation layer)는 컴퓨터 네트워크의 OSI 모형 7계층 가운데 6번째 계층으로, 네트워크의 데이터 번역자로서의 역할을 한다. 이따금 문맥 계층(syntax layer)이라고도 불린다.

MVC 아키텍처는 보통 프론트 컨트롤러(front Controller) 패턴과 함께 사용된다. 프론트 컨트롤러 패턴은 중앙집중형 컨트롤러를 프레젠테이션 계층의 제일 앞에 둬서 서버로 들어오는 모든 요청을 먼저 받아서 처리하게 만든다. 스프링이 제공하는 스프링 서블릿/MVC의 핵심은 DispatcherServlet이라는 프론트 컨트롤러다. 이 DispatcherServlet은 MVC 아키텍처로 구성된 프레젠테이션 계층을 만들 수 있도록 설계되어 있다.

자바 서블릿(Java Servelt)이란 자바를 사용하여 웹페이지를 동적으로 생성하는 서버측 프로그램 혹은 그 사양을 말하며,

프론트 컨트롤러의 역할

  1. 프론트 컨틀롤러는 클라이언트가 보낸 요청을 받아서 공통적인 작업을 먼저 수행한 후에 적절한 세부 컨트롤러로 작업을 위임해주고, 클라이언트에게 보낼 뷰를 선택해서 최종결과를 생성하는 등의 작업을 수행한다.
  2. 예외상황 발생 시 이를 처리하는 것도 프론트 컨트롤러의 역할이다.

서버가 HTTP요청을 받기 시작해서 다시 HTTP로 결과를 응답해주기까지의 과정을 살펴보자.

(1) DispatcherServlet의 HTTP 요청 접수

자바 서버의 서블릿 컨테이너는 HTTP 프로토콜을 통해 들어오는 요청이 스프링의 DispatcherServelt에 할당된 것이라면 HTTP 요청정보를 DispatcherServlet에 전달해준다. web.xml에는 보통 아래와 같이 DispatcherServlet이 전달받을 URL의 패턴이 정의 되어 있다.

<servelt-mapping>
  <servelt-name>Spring MVC Dispatcher Servlet</servelt-name>
  <url-pattern>/app/*</url-pattern>
</servelt-mapping>

이 서블릿-매핑은 URL이 /app로 시작하는 모든 요청을 스프링의 프론트 컨트롤러인 DispatcherServlet에게 할당해주는 것이다.

(2) DispatcherServlet에서 컨트롤러로 HTTP 요청 위임

DispatcherServlet은 URL이나 마라미터 정보, HTTP 명령 등을 참고로 해서 어떤 컨트롤러에게 작업을 위임할지 결정한다. 어떤 컨트롤러/핸들러가 요청을 처리할지 결정했다면, 다음은 해당 컨트롤러 오브젝트의 메소드 호출 후 실제로 웹 요청 처리 작업을 위임할 차례다. DispatcherServlet은 컨트롤러가 어떤 메소드를 가졌고 어떤 인터페이스를 구현했는지 전혀 알지 못한다. 대신 컨트롤러의 종류에 따라 적절한 어댑터를 사용한다. 각 어댑터는 자신이 담당하는 컨트롤러에 맞는 호출 방법을 이용해서컨트롤러에 작업 요청을 보내고 결과를 돌려받아서 DispatcherServlet에게 다시 돌려주는 기능을 갖고 있다. 이렇게 하면 DispatcherServlet이 동시에 여러 가지 타입의 컨트롤러를 사용할 수 있다. 스프링 서블릿/MVC 확장 구조의 기본은 바로 어댑터를 통한 컨트롤러 호출 방식이다. 어떤 어댑터를 사용할지는 DispatcherServlet

(3) 컨트롤러의 모델 생성과 정보 등록

MVC 패넡의 장점은 정보를 담고 있는 모델과 정보를 어떻게 뿌려줄지 알고 있는 뷰가 분리된다는 점이다. 따라서 같은 모델이지만 다른 뷰에 전달되면 다른 방식으로 모델의 정보가 출력되게 할 수 있다. 테이블 뷰에 전달되면 테이블 구조로 나타날 것이고, 그래프 뷰에 전달되면 그래프로, 엑셀 뷰라면 엑셀 문서로 표현된다.

컨트롤러의 작업 분류

  1. 먼저 사용자의 요청 해석
  2. 그에 따라 실제 비즈니스 로직 수행을 위해 서비스 계층 오브젝트에게 작업을 위임
  3. 결과를 받아 모델 생성
  4. 어떤 뷰를 사용할지 결정

컨트롤러가 해야할 마지막 중요한 두 가지 작업 중 하나는 모델 생성 및 모델에 정보 삽입이다. 컨트롤러가 어떤 식으로든 다시 DispatcherServelet에 돌려줘야할 두 가지 정보가 있는데, 그 중 하나가 모델이고 다른 하나는 이다. 모델은 보통 맵에 담긴 정보라고 생각하면 된다. 이름과 그에 대응되는 값의 쌍으로 정보를 만드는 것이다. 물론 복잡한 오브젝트 그래프를 갖는 컬렉션을 하나의 모델 값으로 추가해도 상관 없다.

(4) 컨트롤러의 결과 리턴: 모델과 뷰

모델이 준비 됐으면 다음은 뷰를 결정할 차례다. MVC의 모든 요소가 그렇듯, 뷰도 하나의 오브젝트이다. 컨트롤러가 뷰 오브젝트를 직접 리턴할 수도 있지만, 보통은 뷰의 논리적인 이름을 리턴해주면 DispatcherServelet의 전략인 뷰 리졸버가 이를 이용해 뷰 오브젝터를 생성해준다. 대표적으로 사용되는 뷰는 JSP/JSTL 뷰다. 뷰를 사용하는 전략과 방법도 매우 다양하기 때문에, 일단은 컨트롤러가 뷰에 대한 정보를 돌려준다는 사실만 기억해두고 넘어가자. 컨트롤러가 리턴해주는 정보는 결국 모델과 뷰 두 가지다. 스프링에는 ModelAndView라는 이름의 오브젝트가 있는데, 이 ModelAndView가 DispatcherServelet이 최종적으로 어댑터를 통해 컨트롤러로부터 돌려받는 오브젝트다. 이름 그대로 모델과 뷰, 두가지 정보를 담고 있다. 모델과 뷰를 넘기는 것으로 컨트롤러의 책임은 끝이다. 다시 작업은 DispatcherServelet로 넘어간다.

(5) DispatcherServlet의 뷰 호출과 (6) 모델 참조

DispatcherServlet이 컨트롤러로부터 모델과 뷰를 받은 뒤에 하는 작업은, 뷰 오브젝트에게 모델을 전달해 주고 클라이언트에게 돌려줄 최종 결과물을 생성해 달라고 요청하는 것이다. 보통은 브라우저를 통해 사용자가 결과를 볼테니 브라우저에서 나타날 HTML을 생성하는 일이 가장 흔한 뷰의 작업이다. 기술적으로 보자면 뷰 작업을 통한 최종 결과물은 HttpServletResponse 오브젝트 안에 담긴다.

(7) HTTP 응답 돌려주기

뷰 생성까지의 모든 작업을 마쳤으면 DispatcherServelet은 등록된 후처리기가 있는지 확인하고, 있다면 후처리기에서 후속 작업을 진행한 뒤에 뷰가 만들어준 HttpServelResponse에 담긴 최종 결과를 서블릿 컨테이너에게 돌려준다. 서블릿 컨테이너는 HttpServletResponse에 담긴 정보를 HTTP 응답으로 만들어