[Web] Spring MVC Model
MVC : Model-View-Controller
원래는 제록스 연구소에서 일을 하던 트뤼그베 린즈커그가 처음으로 소개한 개념으로, 데스크톱 어플리케이션용으록 고안되었다.
Model : view 가 렌더링하는데 필요한 데이터이다. 예를 들어, 사용자가 요청한 상품 목록 또는 주문 내역이 해당한다.
View : 웹 어플리케이션에서 view는 실제로 보이는 부분이다. 모델을 사용하여 렌더링하고 뷰는 JSP, JSF, PDF, XML등으로 결과를 표현한다.
Controller : 사용자의 액션에 응답하는 컴포넌트. 컨트롤러는 모델을 업데이트하고, 다른 액션을 수행한다.
MVC Model-1 Architecture
문제점 : JSP 자체에 java코드 + xml 코드가 뒤섞여있어 유지보수가 어렵다
아래는 문제점을 개선한 발전된 형태의 아키텍쳐.
MVC Model-2 Architecture
요청 자체를 서블릿이 받게하고, 서블릿이 bean을 이용해 db에서 데이터를 가져와 jsp 로 결과를 보이게 한다.
로직과 뷰를 분리한 모델이다.
더 자세히 들여다 보자,
프론트 컨트롤러(서블릿) : 사용자의 모든 요청을 받는다. 요청을 처리하지는 않음 - 장점 :
컨트롤러 (핸들러 클래스) : 프론트 컨트롤러로부터 요청을 받아 처리한다. 관련된 URL을 하나의 클래스에서 모두 처리할 수 있어진다. 자바 빈등을 이용해 결과를 만들어 모델에 담아 프론트 컨트롤러에 전달한다.
프론트 컨트롤러는 알맞은 뷰에 모델을 전달해 뷰가 보이게 된다.
프론트 컨트롤러가 모든 요청을 관리하는 방식의 장점은 - 프론트 컨트롤러가 없는 경우를 생각해보면, view에서 요청이 들어왔을 때 컨트롤러로 이동하게 되고 그 컨트롤러에서 바로 로직을 처리하게 됐을 때 1개 요청당 1개의 url을 가진 서블릿을 만들어야하고 이렇게되면 유지보수적인 측면과 코드의 가독성을 따져봤을 때 효율성이 상당히 떨어진다.
따라서 프론트 컨트롤러라는 서블릿을 만들어 클라이언트의 요청은 한 곳에 집중 시켜 개발 및 유지보수에 들어가는 효율성이 높아진다.
이런 구조를 프론트 컨트롤 디자인 패턴이라고 한다.
위의 구조가 Spring Framework Web Module에 이미 구현되어있다!
이 웹 모듈을 Spring MVC 라고 한다.
Spring MVC 기본 동작 흐름
파란 부분 : spring MVC 가 제공하는 부분
보라 부분 : 개발자 구현 부분
녹색 부분 : spring 제공+ 개발자 구현
1. Dispathcer Servlet이 요청을 받는다.
2. 메서드가 무엇인지 Handler Mapping에 물어본다.
3. 어떤 요청에 어떤 controller가 동작할 지는 개발자가 이미 정의 (xml , annotation 등)해놓은 상태에서 여기에 따라 필요로 하는 핸들러매핑 객체들이 생성된다.
4. Dispatcher Servlet이 handler mapping 객체에게서 얻어낸 정보로 Handler Adapter가 실행요청
5. 그 결과는 model에 받아서 Dispatcher Servlet에 전달 ( controller가 반환한 view name 사용)
6. 적절한 view resolver가 어떤 view인지 정보를 얻으면 view를 출력하는 과정을 거친다.
DispatcherServlet
- 프론트 컨트롤러 ( = 회사의 대표번호), 보통 하나만 선언해서 사용
- 클라이언트의 모든 요청을 받은 후 이를 처리할 핸들러에게 넘기고 핸들러가 처리한 결과를 받아 사용자에게 응답 결과를 보여준다.
- 여러 컴포넌트를 이용해 작업을 처리
내부 동작 흐름
1. 요청 선처리 작업
spring framework는 지역화를 지원한다.
(Locale) 지역화 예 : 각 사용자 브라우저 언어 세팅 정보
RequestContextHolder : thread local 객체. 요청을 받아서 응답할 때 까지, httpServletRequest / Response등을 스프링이 관리하는 객체 안에서 사용할 수 있도록 해준다. (스프링이 웹에 종속 될 수 있으므로 권장되는 방법은 아니다. )
FlashMap : spring3에서 추가된 기능. redirect로 값을 전달할 때 사용된다.
? parameter 를 사용하면 url이 복잡해진다. 이를 해결하기 위해 사용되는것. redirect될 때 딱 한 번 값이 지속 될 수 있게 해준다. 리다이렉트 후 조회 하면 바로 정보는 삭제된다.
Multipart 요청 : 사용자가 파일 업로드 했을 경우 사용되는 객체
2. 요청 전달
HandlerExecutionChain이 없다면 페이지가 없는 것이기 때문에 not found 404 에러가 발생
Handler Adapter가 없는 것은 서버에 발생한 오류이기 때문에 Servelet Exception이 발생
HandlerMapping : 어떤 핸들러가 요청을 처리할지에 대한 정보를 가지고 있음
HandlerExecutionChain : 실제로 호출된 핸들러에 대한 참조를 가지고 있음. 즉 무엇이 실행되어야 할지 알고있는 객체이다.
HandlerAdapter : 실제 핸들러를 실행하는 역할. 선택된 핸들러를 실행하는 방법과 응답을 ModelAndView로 변화하는 방법에 대해 알고 있다.
3. 요청 처리
인터셉터 : 일종의 필터. 한 번 걸러내주는 역할! 동작을 처리 하기 전에 한 번 거쳐가는 과정
ModelAndView : controller의 처리 결과를 보여줄 view와 view에서 사용할 값을 전달하는 클래스. 서블릿에서는 모델을 얻고 jsp로 넘길 때 request 객체를 이용했는데, 스프링에서는 종속성을 없애기 위해 ModelAndView를 제공하는 것이므로 이 객체를 사용하는 게 바람직 할 것.
RequestToViewNameTranslator : 컨트롤러에서 뷰 이름이나 뷰 오브젝트를 제공해주지 않았을 경우 url과 같은 요청정보를 참고해 자동으로 뷰 이름을 생성해주는 전략 오브젝트
default : DefaultRequestToViewNameTranslator
4. 예외 처리
HandlerExceptionResolver : 기본적으로 디폴트 리졸버를 등록한다. 예외가 던져졌을 때 어떤 핸들러를 실행할지에 대한 정보를 가지고 있음.
5. 뷰 렌더링
ViewResolver : 컨트롤러가 리턴한 뷰 이름을 참고해서 적절한 뷰 오브젝트를 찾아주는 로직을 가진 전략 오브젝트. 뷰 종류에 따라 뷰 오브젝트를 추가로 설정해줄 수 있음
6. 요청처리 종료
원래는 제록스 연구소에서 일을 하던 트뤼그베 린즈커그가 처음으로 소개한 개념으로, 데스크톱 어플리케이션용으록 고안되었다.
Model : view 가 렌더링하는데 필요한 데이터이다. 예를 들어, 사용자가 요청한 상품 목록 또는 주문 내역이 해당한다.
View : 웹 어플리케이션에서 view는 실제로 보이는 부분이다. 모델을 사용하여 렌더링하고 뷰는 JSP, JSF, PDF, XML등으로 결과를 표현한다.
Controller : 사용자의 액션에 응답하는 컴포넌트. 컨트롤러는 모델을 업데이트하고, 다른 액션을 수행한다.
MVC Model-1 Architecture
문제점 : JSP 자체에 java코드 + xml 코드가 뒤섞여있어 유지보수가 어렵다
아래는 문제점을 개선한 발전된 형태의 아키텍쳐.
MVC Model-2 Architecture
요청 자체를 서블릿이 받게하고, 서블릿이 bean을 이용해 db에서 데이터를 가져와 jsp 로 결과를 보이게 한다.
로직과 뷰를 분리한 모델이다.
더 자세히 들여다 보자,
프론트 컨트롤러(서블릿) : 사용자의 모든 요청을 받는다. 요청을 처리하지는 않음 - 장점 :
컨트롤러 (핸들러 클래스) : 프론트 컨트롤러로부터 요청을 받아 처리한다. 관련된 URL을 하나의 클래스에서 모두 처리할 수 있어진다. 자바 빈등을 이용해 결과를 만들어 모델에 담아 프론트 컨트롤러에 전달한다.
프론트 컨트롤러는 알맞은 뷰에 모델을 전달해 뷰가 보이게 된다.
프론트 컨트롤러가 모든 요청을 관리하는 방식의 장점은 - 프론트 컨트롤러가 없는 경우를 생각해보면, view에서 요청이 들어왔을 때 컨트롤러로 이동하게 되고 그 컨트롤러에서 바로 로직을 처리하게 됐을 때 1개 요청당 1개의 url을 가진 서블릿을 만들어야하고 이렇게되면 유지보수적인 측면과 코드의 가독성을 따져봤을 때 효율성이 상당히 떨어진다.
따라서 프론트 컨트롤러라는 서블릿을 만들어 클라이언트의 요청은 한 곳에 집중 시켜 개발 및 유지보수에 들어가는 효율성이 높아진다.
이런 구조를 프론트 컨트롤 디자인 패턴이라고 한다.
위의 구조가 Spring Framework Web Module에 이미 구현되어있다!
이 웹 모듈을 Spring MVC 라고 한다.
Spring MVC 기본 동작 흐름
파란 부분 : spring MVC 가 제공하는 부분
보라 부분 : 개발자 구현 부분
녹색 부분 : spring 제공+ 개발자 구현
1. Dispathcer Servlet이 요청을 받는다.
2. 메서드가 무엇인지 Handler Mapping에 물어본다.
3. 어떤 요청에 어떤 controller가 동작할 지는 개발자가 이미 정의 (xml , annotation 등)해놓은 상태에서 여기에 따라 필요로 하는 핸들러매핑 객체들이 생성된다.
4. Dispatcher Servlet이 handler mapping 객체에게서 얻어낸 정보로 Handler Adapter가 실행요청
5. 그 결과는 model에 받아서 Dispatcher Servlet에 전달 ( controller가 반환한 view name 사용)
6. 적절한 view resolver가 어떤 view인지 정보를 얻으면 view를 출력하는 과정을 거친다.
DispatcherServlet
- 프론트 컨트롤러 ( = 회사의 대표번호), 보통 하나만 선언해서 사용
- 클라이언트의 모든 요청을 받은 후 이를 처리할 핸들러에게 넘기고 핸들러가 처리한 결과를 받아 사용자에게 응답 결과를 보여준다.
- 여러 컴포넌트를 이용해 작업을 처리
내부 동작 흐름
1. 요청 선처리 작업
spring framework는 지역화를 지원한다.
(Locale) 지역화 예 : 각 사용자 브라우저 언어 세팅 정보
RequestContextHolder : thread local 객체. 요청을 받아서 응답할 때 까지, httpServletRequest / Response등을 스프링이 관리하는 객체 안에서 사용할 수 있도록 해준다. (스프링이 웹에 종속 될 수 있으므로 권장되는 방법은 아니다. )
FlashMap : spring3에서 추가된 기능. redirect로 값을 전달할 때 사용된다.
? parameter 를 사용하면 url이 복잡해진다. 이를 해결하기 위해 사용되는것. redirect될 때 딱 한 번 값이 지속 될 수 있게 해준다. 리다이렉트 후 조회 하면 바로 정보는 삭제된다.
Multipart 요청 : 사용자가 파일 업로드 했을 경우 사용되는 객체
2. 요청 전달
HandlerExecutionChain이 없다면 페이지가 없는 것이기 때문에 not found 404 에러가 발생
Handler Adapter가 없는 것은 서버에 발생한 오류이기 때문에 Servelet Exception이 발생
HandlerMapping : 어떤 핸들러가 요청을 처리할지에 대한 정보를 가지고 있음
HandlerExecutionChain : 실제로 호출된 핸들러에 대한 참조를 가지고 있음. 즉 무엇이 실행되어야 할지 알고있는 객체이다.
HandlerAdapter : 실제 핸들러를 실행하는 역할. 선택된 핸들러를 실행하는 방법과 응답을 ModelAndView로 변화하는 방법에 대해 알고 있다.
3. 요청 처리
인터셉터 : 일종의 필터. 한 번 걸러내주는 역할! 동작을 처리 하기 전에 한 번 거쳐가는 과정
ModelAndView : controller의 처리 결과를 보여줄 view와 view에서 사용할 값을 전달하는 클래스. 서블릿에서는 모델을 얻고 jsp로 넘길 때 request 객체를 이용했는데, 스프링에서는 종속성을 없애기 위해 ModelAndView를 제공하는 것이므로 이 객체를 사용하는 게 바람직 할 것.
RequestToViewNameTranslator : 컨트롤러에서 뷰 이름이나 뷰 오브젝트를 제공해주지 않았을 경우 url과 같은 요청정보를 참고해 자동으로 뷰 이름을 생성해주는 전략 오브젝트
default : DefaultRequestToViewNameTranslator
4. 예외 처리
HandlerExceptionResolver : 기본적으로 디폴트 리졸버를 등록한다. 예외가 던져졌을 때 어떤 핸들러를 실행할지에 대한 정보를 가지고 있음.
5. 뷰 렌더링
ViewResolver : 컨트롤러가 리턴한 뷰 이름을 참고해서 적절한 뷰 오브젝트를 찾아주는 로직을 가진 전략 오브젝트. 뷰 종류에 따라 뷰 오브젝트를 추가로 설정해줄 수 있음
6. 요청처리 종료
No comments: