미니 MVC 프레임워크?

6장 미니 MVC 프레임워크 만들기

Front Controller

  • 공통으로 발생하는 요청 처리를 Controller에게 맡기고, 다음 View에 위임하는 디자인 패턴을 말함.
  • 요청 처리를 집중시키면 이 로직이 뷰와 섞이지 않고, 여러 뷰들의 공통역할을 하게 된다. 따라서, 이 로직을 유지보수하고 확장하는 것이 좀 더 수월해진다.
JSP와 Servlet

JSP = 일반적으로 요청 처리보다는 출력 형식에 더 가까움. JSP로 Controller를 만들면 여러가지가 복잡하게 된다. Servlet = 요청 처리코드와 HTML이 분리되기 대문에 유지보수 하기가 쉬워진다.

역할
  • Controller = 요청을 처리하고, 다음 View에 위임하는 시작점.
  • Dispatcher = View 관리와 네비게이션을 담당.
  • View = 클라이언트에게 필요한 정보를 보내는 부분(실제로 브라우저에 보여지는 부분).
FrontController를 적용한 MVC 구조도

!(FrontController Pattern)[]

  1. 웹 브라우저의 요청이 들어오면, 요청을 받고 FrontController가 받아서 VO객체를 생성하여 클라이언트가 보낸 데이터를 담는다.
  2. 그 후에 VO객체를 저장하고 요청 URL에 따라 실행을 위임
  3. PageController는 DAO를 사용하여 받은 VO객체를 처리함.
  4. DAO는 PageController로부터 받은 데이터를 처리.
  5. PageController는 화면을 만들 때 사용할 데이터를 준비하고 JSP가 사용할 수 있도록 ServletRequest 보관소에 저장.
  6. FrontController는 PageController가 알려준 .jsp 파일로 실행을 위임함. 오류가 생길 경우, /Error.jsp로 실행을 위임.
  7. jsp는 PageController에서 준비한 데이터를 가지고 화면을 생성하여 출력. FrontController는 웹 브라우저의 요청에 대한 응답을 완료.

[출처]열혈강의_자바 웹 개발 워크북_6장

기존의 서블릿이 단독으로 하던 작업을 Front Controller와 Page Controller가 나누어서 역할을 수행함.

  • Front Controller = VO객체의 준비, 뷰 컴포넌트로의 위임, 오류 처리 등. 클라이언트 요청을 적절한 Page Controller에게 전달하는 것을 목적으로 함.
  • Page Controller = 요청한 페이지만을 위한 작업.
디자인 패턴
  • 특정 문제를 해결하기 위한 검증된 방법.
프레임워크
  • 디자인 패턴을 적용해 만든 시스템 중에서 우수 사례를 모아 하나의 개발 틀로 표준화시킨 것.


HttpServletRequest
메서드 설명 반환값
getRequestURL() 요청 URL 리턴(단, 매개변수 제외) http://localhost:9999/web06/member/list.do
getRequestURI() 서버 주소를 제외한 URL /web06/member/list.do
getContextPath() 웹 애플리케이션 경로 /web06
getServletPath() 서블릿 경로 /member/list.do
getQueryString() 요청 매개변수 정보 pageNo=1&pageSize=10


Front Controller와 Page Controller의 호출 규칙 정의

Front Controller와 Page Controller 사이의 호출 규칙을 문법으로 정해두면 규칙에 따라 클래스를 작성하고 호출하기 때문에 프로그래밍의 일관성을 확보할 수 있고 Page Controller가 서블릿이 아니기 때문에 web.xml파일에 등록할 필요가 없어 유지보수가 쉬워진다.

(호출 규칙은 인터페이스를 통해서 정의함.)

인터페이스를 통한 호출규칙을 정의함으로써 더 이상 Forwarding이나 including 방식을 사용하지 않게 된다.

또한, Page Controller와 Front Controller가 데이터를 주고받기 위해서 Map객체를 사용하는데 이는 서블릿 기술에 종속되는 것을 줄여 Page Controller의 재사용성을 높이기 위해서이다.

Interface의 사용에 따른 변화
  • 예외 처리를 할 필요가 없음(예외가 발생했을 경우 호출자인 Front Controller에게 던지면 됨).
  • 유지보수가 쉬워진다.
  • 재사용성이 높아짐.


DI(Dependency Injection)을 이용한 의존성 관리

Controller가 작업을 하려면 데이터를 가져다 줄 DAO가 필요함. 이러한 DAO를 의존객체라고 하고 이 관계를 의존관계에 있다고 한다.

1. 의존 객체를 사용하는 방법

의존 객체를 사용하는 방법은 doGet()이 호출될 때마다 MemberDao객체를 생성하기 때문에 비효율적임.

2. 의존 객체를 미리 생성해두고 필요할 때 사용하는 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			ServletContext sc = this.getServletContext();
			MemberDao memberDao = (MemberDao) sc.getAttribute("memberDao");

			request.setAttribute("members", memberDao.selectList());

			request.setAttribute("viewUrl", "/member/MemberList.jsp");
		}
		catch(Exception e) {
			throw new ServletException(e);
		}
	}

ServletContext에서 꺼내는 것이 아니라 Map 객체에서 꺼낸다는 것이 다른 점.

의존 객체와의 결합도 증가에 따른 문제
  • 코드의 잦은 변경.
  • 결합도가 높아져서 코드가 변경될 경우 바로 영향을 받음.
  • 보관소가 변경되면 보관소를 사용하는 모든 코드를 변경해야 함.

  • 대체가 어려움
  • 의존 객체를 다른객체로 대체하기가 어려움.
  • 데이터베이스를 바꾸는 경우 DAO를 사용하는 코드도 변경해야 함.

의존 객체를 외부에서 주입하는 방법

의존객체를 전문으로 관리하는 Java Bean Container가 등장하게 됨.

Bean container는 객체가 실행되기 전에 그 객체가 필요로 하는 의존 객체를 주입해 주는 역할을 수행한다. 이런방식으로 의존 객체를 관리하는 것을 의존성 주입(Dependency Injection)이라고 한다.