프런트 컨트롤러 디자인 패턴이란?
웹 애플리케이션을 개발할 때 사용하는 MVC 디자인 패턴은 뷰에서 요청이 들어왔을 때 요청을 받아 처리하는 것은 컨트롤입니다. 그런데 하나의 웹 애플리케이션에는 많은 뷰와 컨트롤러가 존재해서 각각의 뷰와 컨트롤러가 연결되어 독립적으로 실행되면, 서버 입장에서는 현재 웹 애플리케이션 실행에 대하여 일괄적으로 처리하기 어렵습니다.
이럴 때 대표 컨트롤러(Front Controller)를 두고 뷰에서 들어오는 모든 요청을 담당하여 웹 애플리케이션을 실행하는 모든 요청을 일괄적으로 처리할 수있습니다.
이러한 구조를 '프런트 컨트롤 디자인 패턴'이라고 합니다.
구현방법
- URL 패턴지정
프런트 컨트롤러 패턴을 적용할 URL 패턴의 규칙을 정한다.
예를 들어 다음과 같이 "~.do", "~.action"와 같은 요청패턴을 지정합니다.
<a href="memberInsert.do">회원가입</a>
<a href="memberSearch.do">회원 정보 조회</a>
- 프런트 컨트롤러(서블릿) 작성
작성하는 프론트 컨트롤은 서블릿 클래스이다. 그러므로 프런트 컨트롤러은 HttpServlet을 상속 받아 작성한다.1234567891011121314//FrontController.java
package
com.dev.controller;
import
java.io.*;
import
javax.servlet.*;
import
javax.servlet.http.*;
public
class
FrontController
extends
HttpServlet {
... 생략 ...
@Override
public
void
service(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
... 생략 ...
}
}
- 프런트 컨트롤러 등록
작성한 프런트 컨트롤 서블릿 클래스를 web.xml에 등록하고 앞에서 정한 URL 패턴와 프런트 컨트롤러를 맵핑하면 클라이언트가 해당 URL 패턴으로 요청시 맵핑된 프런트컨트롤러가 동작된다.123456789101112131415... 생략 ...
<!-- 프런트 컨트롤러 서블릿 등록 -->
<
servlet
>
<
servlet-name
>front</
servlet-name
>
<
servlet-class
>com.dev.controller.FrontController</
servlet-class
>
</
servlet
>
<!-- URL패턴 맵핑-->
<
servlet-mapping
>
<
servlet-name
>front</
servlet-name
>
<
url-pattern
>*.do</
url-pattern
>
</
servlet-mapping
>
... 생략 ...
- 컨트롤러 인터페이스 작성
컨트롤러 인터페이스는 컨트롤러 기능을 구현하는 메소드를 통일하기 위해 작성합니다. 서브 컨트롤러는 이 인터페이스를 구현하게 되고 프런트 컨트롤러에서 모든 서브 컨트롤러를 통일된 방법으로 실행할 수 있습니다.12345678910111213//Controller.java
package
com.dev.controller;
import
java.io.*;
import
javax.servlet.*;
import
javax.servlet.http.*;
public
interface
Controller {
public
void
execute(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException;
}
- 서브 컨트롤러 작성
서브 컨트롤러는 프런트 컨트롤러 다음에 실제 서비스를 처리하는 컨트롤러를 말하며 앞에서의 컨트롤러 인터페이스를 구현하는 클래스를 작성합니다.1234567891011121314151617181920212223//MemberInsertControlle.java
package
com.dev.controller;
import
java.io.*;
import
javax.servlet.*;
import
javax.servlet.http.*;
public
class
Example1Controller
implements
Controller {
public
void
execute(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
// 1. 파라미터 추출
// 2. 유효성 체크
// 3. VO 객체에 데이터 바인딩
// 4. Service 객체의 데이터 바인딩
// 5. Output View 페이지로 이동
}
}
- 서브 컨트롤러 연결
프런트 컨트롤러 실행이 완료된 후 서브 컨트롤러가 실행되게 하려면, 프런트 컨트롤러는 어떤 요청에 대하여 어떤 서브 컨트롤러가 실행되어야 하는지에 대한 정보를 알고 있어야 합니다. 이러한 정보는 주로 map 객체에 저장하여 저장된 정보에서 서브 컨트롤러를 찾아서 실행합니다.1234567891011121314151617181920212223242526272829303132333435363738394041424344package
com.dev.controller;
import
java.io.*;
import
javax.servlet.*;
import
javax.servlet.http.*;
import
java.util.*;
public
class
FrontController
extends
HttpServlet {
private
static
final
long
serialVersionUID = 1L;
//서브 컨트롤러를 관리하는 객체
HashMap<String, Controller> list =
null
;
@Override
public
void
init(ServletConfig sc)
throws
ServletException {
// 서브 컨트롤러 에 대한 정보를 가지는 객체
list =
new
HashMap<String, Controller>();
// 서브 컨트롤러 연결 및 매핑
list.put(
"/example1.do"
,
new
Example1Controller());
list.put(
"/example2.do"
,
new
Example2Controller());
list.put(
"/example3.do"
,
new
Example3Controller());
}
@Override
public
void
service(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
// /dev/example1.do
String url = request.getRequestURI();
// /dev
String contextPath = request.getContextPath();
// contextPath.length() => 4
// url.substring(4) => /example1.do
String path = url.substring(contextPath.length());
// 서브 컨트롤러를 관리하는 객체에서 path에 해당하는 서브 컨트롤러를 찾아 실행한다.
// list.get("/example1.do");
Controller subController = list.get(path);
subController.execute(request, response);
}
}