* 사내 강의용으로 사용한 자료를 Blog에 공유합니다. Spring을 이용한 Web 개발에 대한 전반적인 내용에 대해서 다루고 있습니다.
Spring MVC의 구조
지금까지 Spring을 이용한 DB에 대한 접근법과 다루는 법에 대해서 알아보았습니다. 엄밀히 말하면 이 부분은 MVC pattern의 M에 해당되는 내용들입니다. Spring은 구조화된 MVC 구조를 제공하며, Layer 기반의 잘 정형화된 서비스 패턴을 제공합니다. Spring은 MVC를 기반으로 하는 Web Framework를 제공하고 이는 org.springframework.web 안에 제공되어 있습니다.
이제부터 사용할 package인 org.springframework.web에서는 C와 V에 대한 내용들을 다루고 있습니다.
Controller
간단하게 말해서, Controller는 URL과 상호동작하는 Class입니다.
/wpwoms/appuser/getshoplist 라는 URL이 호출되었을 때, Http Request가 연결되는 Class를 의미합니다.
기술적으로는 굉장히 어려운 영역입니다. 이는 Servlet container의 Http Request가 어떻게 해석이 되며, 이 해석된 Http Request에 따라 어떤 class의 어떤 method를 선택할 지에 대한 복잡한 연결을 계속해서 이어가야지 됩니다.
Controller는 기본적으로 다음과 같은 일을 합니다.
1. Servlet이 넘겨주는 HttpServletRequest를 처리한다.
2. Servlet으로 HttpServletResponse를 보내준다.
3. Cookie, Session 에 대한 동기화 작업을 지원한다.
View
/wpwoms/appuser/getshoplist 라는 URL이 호출되었을 때, Http Request가 연결되는 Class를 의미합니다.
기술적으로는 굉장히 어려운 영역입니다. 이는 Servlet container의 Http Request가 어떻게 해석이 되며, 이 해석된 Http Request에 따라 어떤 class의 어떤 method를 선택할 지에 대한 복잡한 연결을 계속해서 이어가야지 됩니다.
Controller는 기본적으로 다음과 같은 일을 합니다.
1. Servlet이 넘겨주는 HttpServletRequest를 처리한다.
2. Servlet으로 HttpServletResponse를 보내준다.
3. Cookie, Session 에 대한 동기화 작업을 지원한다.
View
View는 HTML 영역이라고 생각하시면 됩니다. 어찌보면 단순한 영역일수도 있지만... 이 부분이 어마어마한 노가다를 요구하는 부분입니다. ㅠ-ㅠ
View는 Controller가 보내주는 데이터를 Html로 표현하는 영역이라고 생각하면 됩니다.
MVC Model이 서로간에 하는 일을 간단히 표현하면 다음 그림과 같습니다.
Front Controller
기존 servlet application 작성시에, url에 각각의 servlet을 등록해서 사용하는 것을 알고 있습니다. 일반적인 MVC 구조의 Web Application은 Front Controller pattern이라고 해서, 가장 최 상단 Front Controller가 모든 Web의 Request를 처리합니다. 그리고, 처리된 Request에 따라 맞는 Controller를 찾아서 호출해주는 형식입니다. Spring에서는 org.springframework.web.servlet.DispatcherServlet에서 FrontController를 담당합니다. 참고로, .NET에서는 ASP .NET MVC에서는 ControllerFactory가 이 일을 합니다.
Controller
org.springframework.web.servlet.DispatcherServlet에서 처리된 request가 전달되는 영역입니다. 여기에서 HTML의 경우, 화면에 보여줄 model을 생성 하고, 또는 REST API의 경우에는 보내질 객체를 결정하게 됩니다.
View
View
사용자, Client에게 전달될 내용입니다. Html이 될 수도 있고, JSON이 될 수도 있고, Excel File이 될 수도 있습니다.
model
MVC에서의 M과는 다른 개념입니다. 기존 MVC에서의 Model은 BL 또는 Persistance Layer의 각 model 또는 entity를 의미하지만, 이곳의 model은 View Model입니다. View에 표시되는 model은 Controller에서 작성이 되는 경우도 있고, Domain Model에서 넘겨온 값을 그대로 이용하는 경우도 있습니다. 기존에 Application의 데이터 흐름에서 이야기한 DTO, VO가 여기에 속하게 됩니다.
Spring MVC에서의 Request 처리 과정
Spring MVC는 Web Request를 다음과 같은 순서로 처리되게 됩니다.
model
MVC에서의 M과는 다른 개념입니다. 기존 MVC에서의 Model은 BL 또는 Persistance Layer의 각 model 또는 entity를 의미하지만, 이곳의 model은 View Model입니다. View에 표시되는 model은 Controller에서 작성이 되는 경우도 있고, Domain Model에서 넘겨온 값을 그대로 이용하는 경우도 있습니다. 기존에 Application의 데이터 흐름에서 이야기한 DTO, VO가 여기에 속하게 됩니다.
Spring MVC에서의 Request 처리 과정
Spring MVC는 Web Request를 다음과 같은 순서로 처리되게 됩니다.
1. Request -> DispatcherServlet : Request가 처음 들어오게 됩니다.
2. DispatcherServlet -> Handler Mapping : DispatcherServlet은 Request를 분석하고 Mapping 중에서 Request와 동일한 Mapping을 찾아냅니다.
3. Handler Mapping -> DispatcherServlet : 찾아진 Handler Mapping을 DispatcherServlet에 전달해줍니다.
4. DispatcherServlet -> Controller : Handler Mapping에서 찾아진 Controller측에 Http Request를 전달해줍니다.
5. Controller -> DispatcherServlet : ModelAndView 객체를 보내줍니다. ModelAndView객체는 View의 이름과 View에 표시될 데이터를 가지고 있습니다.
6. DispatcherServlet -> View Resolver : View이름을 가지고 View를 처리하는 View Resolver에 ViewName을 전달합니다.
7. View Resolver -> DispatcherServlet : 이름에 맞는 View를 return 시켜줍니다.
8. DispatcherServlet -> View : View에 표시될 데이터를 가지고 있는 model을 보내줍니다.
9. View -> DispatcherServlet : model을 이용해서 View를 render 시키고, 그 결과를 DispatcherServlet에 보내줍니다.
10. DispatcherServlet -> Response : View로부터 받은 render된 결과를 Client에게 보내주게 됩니다.
위 그림과 순서는 머리에 익혀두고 있어야지 됩니다. Spring이 우리에게 감춰버리는 부분이기 때문에, 개발을 할때에는 자주 쓰이는 부분이 아니지만 디버그나 문제가 발생했을 때, 어떤 영역에서의 문제인지 확인할 필요가 있을 때 사용되는 지식입니다.
2. DispatcherServlet -> Handler Mapping : DispatcherServlet은 Request를 분석하고 Mapping 중에서 Request와 동일한 Mapping을 찾아냅니다.
3. Handler Mapping -> DispatcherServlet : 찾아진 Handler Mapping을 DispatcherServlet에 전달해줍니다.
4. DispatcherServlet -> Controller : Handler Mapping에서 찾아진 Controller측에 Http Request를 전달해줍니다.
5. Controller -> DispatcherServlet : ModelAndView 객체를 보내줍니다. ModelAndView객체는 View의 이름과 View에 표시될 데이터를 가지고 있습니다.
6. DispatcherServlet -> View Resolver : View이름을 가지고 View를 처리하는 View Resolver에 ViewName을 전달합니다.
7. View Resolver -> DispatcherServlet : 이름에 맞는 View를 return 시켜줍니다.
8. DispatcherServlet -> View : View에 표시될 데이터를 가지고 있는 model을 보내줍니다.
9. View -> DispatcherServlet : model을 이용해서 View를 render 시키고, 그 결과를 DispatcherServlet에 보내줍니다.
10. DispatcherServlet -> Response : View로부터 받은 render된 결과를 Client에게 보내주게 됩니다.
위 그림과 순서는 머리에 익혀두고 있어야지 됩니다. Spring이 우리에게 감춰버리는 부분이기 때문에, 개발을 할때에는 자주 쓰이는 부분이 아니지만 디버그나 문제가 발생했을 때, 어떤 영역에서의 문제인지 확인할 필요가 있을 때 사용되는 지식입니다.
Maven을 이용한 Hello World Web App
maven을 이용해서 Simple web application을 작성하는 법을 간단히 알아보도록 하겠습니다. 이 프로젝트는 전반적인 프로젝트들의 뼈대가 될 것입니다.
Maven Project를 선택해줍니다.
maven-archetype-webapp을 선택해줍니다.
groupId와 artifact Id를 넣어주고, Project를 생성합니다.
지금 상태는 기본적으로 JRE1.5를 기반으로 한 Project가 구성이 되어있고, web application으로 eclipse에서 인식도 못하는 상태입니다. 프로젝트를 좀 손을 봐줘야지 됩니다.
pom.xml을 수정해서 JRE1.7기반으로 변경합니다.
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.0</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin>
Project에서 우클릭 > Property에 들어가서 Project Facets를 선택합니다.
Convert to faceted from... 을 클릭합니다.
Dynamic Web Module과 JavaScript를 선택합니다.
하단에 나오는 Further configuration available 을 클릭합니다.
ContextRoot를 artifactId와 동일하게 설정하고, Context directory를 src/main/webapp 으로 수정하고, Generate web.xml deployment descriptor를 선택합니다.
프로젝트가 다음 모습이 되는지 확인합니다.
다시 Project 우클릭 > Property에 들어가서, Deployment Assembly를 선택합니다.
Add를 눌러, Java Build Path Entities를 추가, Maven Dependencies를 추가합니다.
/src/test/java를 제거합니다.
다음과 같이 Web Depolyment Assembly가 되어 있는지를 확인합니다.
다음과 같이 Web Depolyment Assembly가 되어 있는지를 확인합니다.
Server에 추가 후, Hello World!가 나오는지 확인합니다.
이번에는 Tomcat이 아닌 jetty를 이용해서 실행해보도록 하겠습니다.
pom.xml > build > plugins 에 다음 항목을 추가합니다.
<plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.0.1.v20130408</version> </plugin>
추가후 mvn jetty:run 을 이용해서 jetty를 실행시켜주세요. 그리고 jetty는 이 버젼에 유의해서 사용해야지 됩니다. jetty 9.0.0 버전은 심각한 오류를 가지고 있기 때문에 절대로 사용해서는 안됩니다.
Summary
maven을 이용해서 web application을 작성하는 법을 한번 알아봤습니다. maven으로 작업하는 경우에는 maven way 라고 하는 절대적인 폴더 위치를 비롯해서 프로젝트의 구성을 그대로 맞춰줘야지만 쉽게 사용할 수 있습니다. 물론, 위치들을 변경하는 방법역시 존재하지만 이와 같은 공통적인 방법을 통해서 구성하는 것이 좋습니다. 이 폴더의 구조에 대해서는 반드시 외우거나 숙지해주시길 바랍니다.