# Project Structure
더보기
- MVC 스타일의 이해를 돕기 위한 프로젝트구조이다.
- 자바 소스에는 Controller와 Model을 구현하는 control, dao, service 패키지가 있고, WebContent 아래에는 View를 구현하는 jsp 파일이 있다.
MVC 2 패턴은 크게 Model, View, Controller로 구성됩니다. Model과 Controller는 자바 프로그램으로 구성되고, 뷰는 JSP 파일로 구성됩니다.
MVC 패턴과 JSP 모델 2 구조의 매핑
- 컨트롤러(Controller) = 서블릿 = control 패키지
- 모델(Model) = 로직 처리 클래스, 자바빈 = dao, service 패키지
- 뷰(View) = JSP = WebContent/*.jsp
- 사용자(User) = 웹 브라우저 내지 휴대폰과 같은 기기
# 컨트롤러와 모델의 흐름
- 과정1 : 웹 브라우저가 전송한 HTTP 요청을 받는다. 서블릿의 doGet() 메소드나 doPost() 메소드가 호출된다.
- 과정2 : 웹 브라우저가 어떤 기능을 요청했는지 분석한다. 예를 들어, 게시판 목록을 요청했는지, 글쓰기를 요청했는지 알아낸다.
- 과정3 : 모델을 사용하여 요청한 기능을 수행한다.
- 모델에서 처리
- 과정4 : 컨트롤러의 요청을 받아 비즈니스 로직을 수행한다.
- 과정5 : request나 session의 setAttribute() 메소드를 사용하여 결과 값을 속성에 저장한다. (저장된 결과 값은 뷰인 JSP에서 사용한다) 또한 사용될 뷰(jsp)를 리턴한다.
- 모델에서 처리
- 과정6 : 웹 브라우저에 결과를 전송할 JSP를 선택한 후, 해당 JSP로 포워딩한다. 경우에 따라 리다이렉트를 하기도 한다.
# Open Source Controller
- Controller Source Code and Description
더보기
control 패키지의 Controller입니다. 아래의 소스는 Controller의 유명한 오픈소스로 알려져 있다고 합니다. Controller를 정의하기 전에, 로직을 처리를 정의하기 위해 인터페이스를 만듭니다.
- service.CommandProcess
package service;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface CommandProcess{
public String requestPro(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException;
}
CommandProcess 인터페이스를 통해 명령어 비지니스 로직 처리 메소드(requestPro)를 정의합니다.
- control.Controller
package control;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import service.CommandProcess;
/**
* Controller : Service(Command) --> Business Logic
*/
@WebServlet("/Controller")
public class Controller extends HttpServlet{
private static final long serialVersionUID = 1L;
private Map<String, Object> commandMap = new HashMap<String, Object>();
public Controller(){ super(); }
public void init(ServletConfig config) throws ServletException {
// web.xml에서 propertyConfig에 해당하는 init-param의 값을 읽어옴.
String props = config.getInitParameter("config");
// 명령어와 처리클래스의 매핑정보를 저장할 Properties 객체 생성
Properties pr = new Properties();
FileInputStream f = null;
try {
String configFilePath = config.getServletContext().getRealPath(props);
f = new FileInputStream(configFilePath);
// command.properties 파일의 정보를 Properties 객체에 저장
pr.load(f);
} catch (IOException e) {
throw new ServletException(e);
} finally {
if (f != null) try { f.close(); } catch (IOException e) { }
}
//Iterator 객체는 Enumeration 객체를 확장시킨 개념의 객체
Iterator keyIter = pr.keySet().iterator();
//객체를 하나씩 꺼내서 그 객체명으로 Properties 객체에 저장된 객체에 접근
while(keyIter.hasNext()) {
String command = (String)keyIter.next();
String className = pr.getProperty(command);
try {
Class commandClass = Class.forName(className);//해당 문자열을 클래스로 만든다.
Object commandInstance = commandClass.newInstance(); //해당 클래스의 객체를 생성
commandMap.put(command, commandInstance); // Map 객체인 commandMap에 객체 저장
} catch(Exception e) {
throw new ServletException();
}
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
requestPro(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestPro(request, response);
}
// CommandProcess 인터페이스의 메소드 requestPro(request, response): 사용자의 요청을 분석해서 해당 작업을 처리한다.
public void requestPro(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String view = null;
CommandProcess com = null;
try {
String command = request.getRequestURI();
System.out.println(command);
command = command.substring(request.getContextPath().length()); // real path만큼 자름.
com = (CommandProcess)commandMap.get(command);
System.out.println("command --> "+command);
System.out.println("com --> "+com);
// view로 이동함.
view = com.requestPro(request, response);
System.out.println("view --> "+view);
}catch(Throwable e) {throw new ServletException(e);}
RequestDispatcher dispatcher = request.getRequestDispatcher(view);
dispatcher.forward(request, response);
}
}
Controller의 init()메소드에서는 설정 파일로 부터 받아온 설정 정보를 저장하고, Properties 객체를 생성하여 command.properties의 파일의 Properties 정보를 저장한다. (command.properties 파일은 명령어와 명령어 처리 클래스를 매핑한 파일이다.)
- 아래의 코드는 command.properties의 예제를 보여줍니다. ip주소/list.do를 입력하면 listAction이 수행됩니다.
/list.do = service.ListAction
- 아래의 코드는 Controller 코드의 일부입니다. 이 코드(Class와 Object 처리)를 통해 우리는 Controller 소스 코드를 직접 수정하지 않고, command.properties에 추가함으로써, 명령어와 처리 클래스를 연결할 수 있습니다.
Class commandClass = Class.forName(className);//해당 문자열을 클래스로 만든다.
Object commandInstance = commandClass.newInstance(); //해당 클래스의 객체를 생성
commandMap.put(command, commandInstance); // Map 객체인 commandMap에 객체 저장
- 우리는 소스파일의 doGet(request, response)와 doPost(request, response) 메소드에서 처리를 requestPro(request, response)로 넘겨주는 것을 볼 수 있습니다.
- requestPro에서는 명령을 받아 명령을 분석하고, 명령을 처리할 객체를 생성하여 그 객체를 통해 view를 반환 받는 것을 볼 수 있습니다.
public void requestPro(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String view = null;
CommandProcess com = null;
try {
String command = request.getRequestURI();
System.out.println(command);
command = command.substring(request.getContextPath().length()); // real path만큼 자름.
com = (CommandProcess)commandMap.get(command);
System.out.println("command --> "+command);
System.out.println("com --> "+com);
// view로 이동함.
view = com.requestPro(request, response);
System.out.println("view --> "+view);
}catch(Throwable e) {throw new ServletException(e);}
RequestDispatcher dispatcher = request.getRequestDispatcher(view);
dispatcher.forward(request, response);
}
# 개발 순서
- [Dynamic Web Project] 생성하기
- DBMS를 이용해 사용할 데이터베이스 생성
- Project의 패키지 나누기(control, dao, service)
- control은 Controller를 위한 패키지
- dao와 service는 Model을 위한 패키지
- dao 패키지에 DAO와 DTO 클래스 정의하기
- 생성한 데이터베이스의 형식에 맞는 dto 객체 만들기
- DBCP를 이용한 DB연결을 위해 WebContent의 META-INF 폴더 아래 context.xml 에 디비 정보 구현
- dao 객체에는 부가 기능을 제외한 DBCP를 이용하여 데이터베이스 연결 수행
- service 패키지에서 명령처리를 위한 인터페이스 생성
- CommandProcess - requestPro 메소드
- command.properties에 명령어와 명령 처리 클래스 정의
- ex) /list.do = service.ListAction
- control 패키지의 Controller 클래스 정의하기
- init(config) 메소드에서 WebContent/WEB-INF/command.properties에 설정된 명령어와 명령처리 클래스를 받아와서 명령어에 따른 명령 처리 클래스의 객체를 생성함.
- requestPro 메소드를 정의하여 명령 받은 것을 분석하고 명령에 따른 명령처리 클래스를 실행하여 받은 view와 request 속성을 view로 포워딩한다.
- service의 Action 클래스 정의하기. (ListAction)
- CommandProcess를 상속받아 requestPro 메소드를 오버라이딩한다.
- requestPro 메소드에서 request의 속성을 설정하고 페이징 처리를 하고, list.jsp를 반환한다.
- WebContent에 jsp 파일(view) 생성하여 기술. (list.jsp)
- 이때, Action 클래스에서 request나 session을 통해 받은 속성을 이용하여 기술한다.
- index.jsp에 메인화면에 등록할 페이지로 이동시키는 코드를 작성한다.
- <script>location.href="list.do"</script>
- 하지만 우리는 list.do로 list.jsp로 이동할 수 없으니, 반드시 web.xml의 설정파일에 기술해줘야한다.
- Web.xml 파일 설정
- web.xml 파일은 Tomcat의 실행환경에 대한 정보를 담당하는 환경설정 파일로, 각종 servlet의 설정과 servlet 매핑, 필터, 인코딩 등을 담당한다.
- web.xml 파일에 서블릿 파일인 Controller와 위치를 등록하고, config파일과 위치를 등록한다. 또한 servlet 파일이 실행될 url 확장자과 Controller를 매핑하는 코드를 작성해준다.
- web.xml 파일
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>och16</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Controller</servlet-name>
<servlet-class>control.Controller</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/command.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Controller</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
[ References ]
- 최범균의 JSP2.3 웹 프로그래밍 기초부터 중급까지, 최범균, 가메출판사
- 이 포스팅은 청년취업 아카데미 [JAVA Framework 실무 개발자 단기 과정]에서 들은 내용을 바탕으로 기술되었습니다. -
'청년취업아카데미 > DayLog' 카테고리의 다른 글
[ Tiles ] Tiles 란? (0) | 2019.08.13 |
---|---|
[ JSP ] Day 14 - ① MVC (0) | 2019.07.29 |
[ JS ] Day 13 - ③ AJAX 예제 - 아이디 중복 확인 (0) | 2019.07.26 |
[ JS ] Day 13 - ② Ajax (0) | 2019.07.26 |
[ JS ] Day 13 - ① 브라우저 객체 (0) | 2019.07.26 |