[BACKEND]MVC 패턴 구현
※ MVC 패턴 구현
모델 2 구조 기반의 MVC 패턴 구현은 JSP 개발자라면 반드시 습득해야 할 기본 기법입니다.
1. 모델2구조와 MVC 패턴
JSP 웹 어플리케이션의 구조는 크게 모델 1 구조와 모델 2 구조로 나누어 집니다.
JSP에서 모든 로직과 출력을 처리하느냐 아니면 JSP에서는 출력만 처리하느냐에 따라서
모델 1 구조와 모델 2 구조로 구분됩니다.
1) 모델1 구조 : "중요_1) 모델1 vs 모델 2 비교.pdf" 참고 바랍니다.
모델1 구조는 JSP를 이용한 단순한 모델입니다.
지금까지 예제로 작성한 JSP 페이지가 모델1 구조를 사용하고 있습니다.
보통 처음 JSP를 배울 때 사용하는 구조가 모델 1 구조입니다.
모델1 구조는 웹 브라우저의 요청을 JSP가 직접 처리합니다.
웹 브라우저의 요청을 받은 JSP는 자바빈이나 서비스 클래스를 사용해서
웹 브라우저가 요청한 작업을 처리하고 그 결과를 클라이언트에 출력합니다.
JSP 페이지에서 웹 브라우저가 요청한 것들을 처리한다는 것은
JSP 페이지에 비즈니스 로직을 처리하기 위한 코드와
웹 브라우저에 결과를 출력하는 코드가 섞인다는 것을 의미 합니다.
예를 들어, 앞서 방명록 예제를 보면 하나의 JSP 페이지에서
서비스 클래스를 통해서 (글쓰기, 읽기 등) 원하는 작업을 수행하고
그 결과를 출력했는데, 이것이 모델1 구조의 전형적인 예입니다.
2) 모델2 구조 : "중요_1) 모델1 vs 모델 2 비교.pdf" 참고 바랍니다.
모델2 구조는 모델1 구조와 달리 웹 브라우저의 요청을 하나의 서블릿이 받습니다.
서블릿은 웹 브라우저의 요청을 알맞게 처리한 후 그 결과를 보여줄
JSP 페이지로 포워딩 합니다. 포워딩을 통해 요청 흐름을 받은 JSP 페이지는
결과 화면을 클라이언트에 전송합니다. 이 과정에서 서블릿이 로직을 처리합니다.
모델2 구조의 특징은 웹 브라우저의 모든 요청을 단일 진입점, 즉 하나의 서블릿에서
처리한다는 점입니다. 하나의 서블릿이 웹 브라우저의 모든 요청을 받기 때문에,
서블릿은 웹 브라우저의 요청을 구분하는 방법이 필요합니다. 서블릿은 웹 브라우저의
요청을 처리한 후 웹 브라우저에 보이게 될 응답 화면을 생성할 JSP를 선택합니다.
모델2 구조의 이러한 특징 때문에, MVC(Model-View-Controller : 모델-뷰-컨트롤러)
패턴을 이용해서 웹 어플리케이션을 구현할 때 모델2 구조를 사용합니다.
3) MVC 패턴 : "중요_2) MVC 패턴 구조.pdf" 참고 바랍니다.
MVC(Model-View-Controller : 모델-뷰-컨트롤러) 패턴은
웹 개발자라면 반드시 알아야 하는 패턴입니다. MVC 패턴은 JAVA FX와 같은
UI 컴포넌트뿐만 아니라 웹 어플리케이션 개발 영역에서도 보편적으로 사용되고 있습니다.
이름에서도 알 수 있겠지만 MVC 패턴은 크게 모델, 뷰, 컨트롤러의 세 부분으로 구성되며,
각각의 요소는 다음과 같은 역할을 담당답니다.
[다음 : MVC(Model-View-Controller : 모델-뷰-컨트롤러) 패턴 구성 요소 역할]
• 모델 : 비즈니스 영역의 로직을 처리합니다.
• 뷰 : 비즈니스 영역에 대한 프레젠테이선 뷰(즉, 사용자가 보게 될 결과 화면)를 담당합니다.
• 컨트롤러 : 사용자의 입력 처리와 흐름 제어를 담당합니다.
사용자는 원하는 기능을 처리하기 위한 모든 요청을 컨트롤러에 보냅니다.
모델은 비즈니스와 관련된 기능을 제공하는데, 컨트롤러는 이 모델을 이용해서
사용자의 요청을 처리합니다. 모델을 사용하여 알맞은 비즈니스 로직을 수행한 후
컨트롤러는 사용자에게 보여줄 뷰를 선택합니다.
선택된 뷰는 사용자에게 알맞은 결과 화면을 보여줍니다. 뷰가 사용자에게
결과 화면을 보여줄 때에는 데이터가 필요한데, 이 데이터는 컨트롤러를 통해서 전달 받습니다.
MVC 패턴의 핵심은 다음과 같습니다.
• 비즈니스 로직을 처리하는 모델과 결과 화면을 보여주는 뷰를 분리합니다.
• 어플리케이션의 흐름 제어나 사용자의 처리 요청은 컨트롤러에 집중됩니다.
모델은 비즈니스와 관련된 로직을 처리하면 될 뿐 사용자에게 보여줄 화면이나 흐름 제어에
대해서는 처리하지 않습니다. 반대로 뷰는 사용자에게 알맞은 화면을 보여주는 역할만 수행할 뿐,
비즈니스 로직이나 흐름 제어 등을 처리하지 않습니다.
이렇게 모델과 뷰가 분리되어 있기 때문에 모델의 내부 로직이 변경되더라도 뷰는 영향을 받지 않고,
반대로 뷰와 모델이 직접 연결되어 있지 않기 때문에 내부 구현 로직에 상관없이 뷰를 변경할 수 있습니다.
또한, 컨트롤러는 사용자의 요청에 대해서 알맞은 모델을 사용하고 사용자에게 보여줄 뷰를 선택하면 됩니다.
비즈니스 로직에는 포함되지 않지만, 전체 웹 어플리케이션에 일괄적으로 적용되는 기능(예를 들어, 사용자 인증)을
컨트롤러에서 처리하게 됩니다.
웹 어플리케이션의 흐름 제어나 보안 설정이 변경되면 컨트롤러만 변경하면 되고, 새로운 타입의
사용자(예를 들어, 새로운 모바일 기기의 추가)가 새롭게 추가되는 경우
컨트롤러나 모델에 상관없이 새로운 뷰를 추가하면 됩니다. 즉,MVC 패턴을 사용함으로써
유지보수 작업이 쉬워지고 어플리케이션을 쉽게 확장할 수 있게 됩니다.
4) MVC 패턴과 모델2 구조의 매핑
앞서 JSP의 모델2 구조와 MVC 패턴이 비슷한 것을 알 수 있는데,
실제로 모델 2 구조와 MVC 패턴은 완벽하게 일치합니다. 이 둘 사이의 관계를 살펴보면 다음과 같습니다.
[다음]
• 컨트롤러 = 서블릿
• 모델 = 로직 처리 클래스,자바빈
• 뷰 = JSP
• 사용자 = 웹 브라우저 또는 휴대폰과 같은 다양한 기기
모델2 구조에서 웹 브라우저의 요청은 서블릿으로 전달된다고 했는데,
웹 브라우저의 요청은 곧 사용자의 입력이 됩니다.
서블릿은 비즈니스 로직을 수행하는 클래스를 사용하여
웹 브라우저의 요청을 처리하며 뷰의 역할을 하는 JSP 페이지를 이용해서 처리 결과를 보여주게 됩니다.
5) MVC의 컨트롤러 : 서블릿
모델2 구조에서 서블릿은 MVC 패턴의 컨트롤러 역할을 합니다. 서블릿은 웹 브라우저의 요청과
웹 어플리케이션의 전체적인 흐름을 제어합니다.
컨트롤러 역할을 하는 서블릿은 크게 5단계의 과정을 거쳐 웹 브라우저의 요청을 처리합니다.
각 과정에 대해 더욱 자세하게 살펴보면 다음과 같습니다.
[다음 : 컨트롤러 역할을 하는 서블릿의 웹 브라우저 요청 처리 5단계]
• 과정1 : 웹 브라우저가 전송한 HTTP 요청을 받습니다.
서블릿의 doGet() 메서드나 doPost() 메서드가 호출됩니다.
• 과정2 : 웹 브라우저가 어떤 기능을 요청했는지 분석합니다.
예를 들어, 게시판 목록을 요청했는지, 글쓰기를 요청했는지 알아냅니다.
• 과정3 : 모델을 사용하여 요청한 기능을 수행합니다.
• 과정4 : 모델로부터 전달받은 결과물을 알맞게 가공한 후, request나 session의 setAttribute()
메서드를 사용하여 결과값을 속성에 저장합니다.
이렇게 저장한 결과값은 뷰인 JSP에서 사용합니다.
• 과정5 : 웹 브라우저에 결과를 전송할 JSP를 선택한 후, 해당 JSP로 포워딩합니다.
경우에 따라 리다이렉트를 하기도 합니다.
비즈니스 로직의 처리는 모델에서 이루어집니다. 서블릿은 모델이 내부적으로
어떻게 비즈니스 로직을 처리하는지 알 필요 없이, 웹 브라우저의 요청에 따라 알맞게 모델을
사용하여 요청 기능을 실행하고 그 결과를 뷰인 JSP에 전달하면 됩니다.
웹 브라우저의 결과를 보여줄 JSP 페이지는 컨트롤러 서블릿이 선택합니다.
이때, 요청 처리 결과는 request나 session에 저장해서 뷰 역할을 하는 JSP 페이지에 전달합니다.
6) MVC의 뷰 : JSP
모델2 구조에서 JSP는 뷰 역할을 담당합니다. 비즈니스 로직과 관련된 코드가 없는 점을 제외하면
일반 JSP와 동일한 형태를 취한다. 뷰 역할을 하는 JSP는 컨트롤러에서
request 기본 객체나 session 기본 객체에 저장한 데이터를 사용하여 웹 브라우저에
알맞은 결과를 출력합니다. 뷰 JSP는 컨트롤러 서블릿처럼 일반적인 처리 순서가 정해져 있지는 않습니다.
뷰 역할을 하는 JSP는 웹 브라우저가 요청한 결과를 보여주는 프레젠테이션의 역할을 할 뿐만 아니라
웹 브라우저의 요청을 컨트롤러에 전달해주는 매개체가 되기도 합니다.
예를 들어, 웹 브라우저가 게시판 글 목록 보기를 요청하여 그 결과를 'BoardList.jsp' 뷰를 사용하여
출력했다고 하면, 이때, 'BoardList.jsp'에는 [글쓰기]와 같은 링크가 존재할 것이며,
이 [글쓰기] 링크는 컨트롤러에 연결되어 있을 것입니다. 즉, 뷰 역할을 하는 JSP는
웹 브라우저가 지속적으로 컨트롤러에 요청을 보낼 수 있는 링크나 폼을 제공해서
웹 브라우저가 업무 흐름에 따라 컨트롤러에 알맞은 요청을 보낼 수 있도록 합니다.
7) MVC의 모델
컨트롤러는 서블릿을 통해서 구현하고 뷰는 JSP를 통해서 구현하는데 모델은 명확하게
어떤 것을 통해서 구현한다는 규칙은 없습니다. 비즈니스 로직을 처리해주면 모델이 될 수 있습니다.
모델이 제공해야 하는 기능은 웹 브라우저의 요청을 처리하는 데 필요한 기능 입니다.
예를 들어, 계좌 이체 기능을 요청했다면 모델은 계좌 이체를 시켜주는 기능을 제공해야 하며,
컨트롤러는 웹 브라우저의 요청이 들어오는 경우 모델의 계좌 이체 기능을 사용하게 됩니다.
다음은 컨트롤러 역할을 하는 서블릿과 모델 간의 통신 구조 처리 흐름을 나타냅니다.
[다음 : 컨트롤러 역할을 하는 서블릿과 모델 간의 통신 구조 처리 흐름]
모델의 일반적은 업무 흐름을 보면, 컨트롤러 서블릿이 웹 브라우저의 요청을 분석하여
알맞은 모델을 호출하면서부터 모델의 기능이 시작됩니다. 모델은 컨트롤러가
요청한 작업을 처리한 후 알맞은 결과를 컨트롤러에게 전달하는데, 이때 처리한 결과값을
저장하는 객체로 보통 자바빈을 사용합니다. 모델은 서비스 클래스나 DAO 클래스를 이용해서
비즈니스 로직을 수행하게 됩니다.
=============================================================================
※ 프로잭트 생성
1) [File] - [New] - [Dynamic Web Project] 메뉴를 실행합니다.
2) New Dynamic Web Project 대화창에서 다음과 같이 설정 후
[Finish] 버튼을 클릭해서 프로젝트를 생성합니다.
a. Project name : MVC_BASIC
b. Target runtime : Apache Tomcat v9.0 (톰켓 런타임을 다른 이름으로 등록했다면 해당 이름 사용)
c. Dynamic web module version : 3.1
3) 프로젝트 생성 후 jstl-1.2.jar 파일을 WebContent/WEB-INF/lib 폴더에 복사합니다.
4) 프로젝트 클릭 - 우클릭 - Properties
- Web Project Settings 에서 Context root: 입력란에 기존 "MVC_BASIC"를 "/"로 변경해 주기 바랍니다.
5) Tomcat 서버 Modules 설정에서 Path 설정을 기존 "/MVC_BASIC"에서 "/" 변경 처리 후 저장합니다.
6) 프로젝트 클릭 선택 - Properties - Java Build Path - Libraries - Add Library
- Server Runtime 에서 Apache Tomcat v9.0 선택 추가 바랍니다.
=============================================================================
2. 모델 2 구조를 이용한 MVC 패턴 구현
1) 모델 2 구조의 구현 방법 : 기본 MVC 패턴 구현 기법
MVC 패턴을 구현하려면 기본이 되는 모델2 구조를 구현하는 방법을 몸에 익혀야 합니다.
왜냐하면, 모델2 구조를 위한 서블릿을 어떻게 구현하는지, 서블릿과 JSP는 어떻게
정보를 주고받는지 등에 대한 기본 개념을 익힌 후에야 비로소 MVC 패턴을 체계적으로
구현하는 방법을 단계적으로 살펴볼 수 있기 때문입니다.
① 서블릿 클래스는 컨트롤러의 역할을 하며,
화면에 출력할 메시지를 생성해서 JSP에 전달합니다.
② JSP는 서블릿으로부터 전달받은 메시지를 화면에 출력합니다.
* JAVA 소스 코딩 : 컨트롤러 서블릿 코드를 사용하는 예제를 작성해 봅니다.
이 예제는 웹 브라우저가 전송한 type 파라미터의 값에 따라서
다른 결과값을 생성해서 뷰에 전달하는 컨트롤러 서블릿입니다.
[src/mvc/simple/SimpleController.java 소스 코딩]
* JSP 소스 코딩 : 뷰 역할을 하는 simpleView.jsp는 컨트롤러가 전달한 값을
단순히 화면에 출력하도록 구현할 것입니다.
[WebContent/simpleView.jsp 소스 코딩]
* web.xml 소스 코딩 : 서블릿 클래스를 실행하려면 web.xml 파일에 요청 URL과
서블릿 간의 매핑을 입력해주어야 합니다.
[WebContent/WEB-INF/web.xml 소스 추가 코딩]
* 중요 : 실행 확인 : "중요_5) SimpleController 예제 실행 순서.jpg" 이미지도 참고 바랍니다.
Run As - Run on Server - SimpleController 실행 (SimpleView.jsp로 실행하면 안됨!)
* 중요 : simpleview.jsp 클릭 - 마우스 우클릭 - Run As - Run on Server
- 웹 주소창에서 simpleView 부분을 simple로 수정 후 ▶ 클릭(결과 : 안녕하세요 나타남)
- simple?type=date (쿼리스트링 붙여주고 ▶ 클릭 : Date() 실행 내용 확인)
- simple?type=greeting (쿼리스트링 붙여주고 ▶ 클릭 : 안녕하세요 결과 확인)
- http://localhost:9001/servlet.do?type=greeting(웹주소에 *.do 형식으로 넣어주고, 쿼리스트링 붙여주고 ▶ 클릭 : 안녕하세요 결과 확인)
- http://localhost:9001/servlet.do?type=date(웹주소에 *.do 형식으로 넣어주고, 쿼리스트링 붙여주고 ▶ 클릭 : Date() 실행 내용 확인)
- http://localhost:9001/service.do?type=greeting(웹주소에 *.do 형식으로 넣어주고, 쿼리스트링 붙여주고 ▶ 클릭 : 안녕하세요 결과 확인)
- http://localhost:9001/service.do?type=date(웹주소에 *.do 형식으로 넣어주고, 쿼리스트링 붙여주고 ▶ 클릭 : Date() 실행 내용 확인)
* 중요 : 간단한 프로젝트는 JSP 모델1 패턴 활용도 괜찮지만,
규모가 큰 웹 프로젝트는 MVC 패턴 개발이 필요합니다.
3. 모델1 구조와 모델2 구조의 선택
모델1 구조와 모델 2 구조는 장단점 이 존재합니다. 이들 장단점을 파악하고 있다면 이제부터
웹 어플리케이션을 구현할 때 상황에 맞게 모델을 선택할 수 있을 것입니다. 이 비교를 통해
무조건적인 선택이 아닌 보다 합리적인 기준으로 모델을 선택할 수 있게 되길 바랍니다.
[다음 : 모델1 구조와 모델 2 구조의 장단점]
모델 구분 장점 단점
모델1 - 배우기 쉽습니다. - 로직 코드와 뷰 코드가 혼합되어 JSP 코드가 복잡해 집니다.
- 기능과 JSP가 직관적으로 연결됩니다. - 뷰 변경 시 논리 코드의 빈번한 복사가 발생해서
코드 중복이 발생하기 쉽습니다. 즉, 유지보수가 힘들어집니다.
모델2 - 로직 코드와 뷰 코드를 분리해서 유지보수가 쉬워집니다. - 자바 언어에 친숙하지 않으면 접근하기가 쉽지 않습니다.
- 컨트롤러 서블릿에서 권한 검사나 인증과 같은 공통 기능 처리가 가능합니다. - 작업량이 많습니다. (커맨드 클래스 + 뷰 JSP)
- 확장이 용이합니다.













@webservlet 삭제


















애노테이션 방식으로 처리하기







url 두개로 할때는??



web servlet이 편리해 보이지만 유지보수관리가 힘든편이다.
유지보수 용이는 web.xml 이 우위