1. Model 1과 Model 2
1) Model 1(p752)
- 뷰와 컨트롤러가 같은 JSP 안에서 실행
- 간단한 웹어플리케이션을 구축할 때 적당
- 개발기간 단축
- 유지 보수가 어려움
- 디자이너와 개발자간의 의사소통이 필요
2) Model 2(p753)
- 컨트롤러와 뷰가 엄격히 구분
- 뷰는 어떠한 처리로직도 포함하지 않음
- 사용자 요청의 집입점은 컨트롤러인 servlet이 담당 모든 흐름을 통제
- 유지 보수 확장이 용이
- 개발자와 디자이너의 작업이 분리
- 중 대형 프로젝트에 적합
- 초기에 구조 설계 시간이 많이 필요
2. MVC 패턴
1) View
- 화면에 내용을 보여주는 역할
- JSP 페이지
2) Model
- 로직을 가지고 있는 부분
- DB와 연동 데이터를 가져와 작업을 처리하거나 처리한 작업의 결과를 데이터로서 DB에 저장
- 데이터를 생성, 저장, 처리하는 역할을 담당
3) Controller
- 어플리케이션의 흐름를 제어 (view와 model사이)
- 서블릿 컨트롤러 사용
예) 컨트롤러 사용 예제(controller와 view)
http://127.0.0.1/study/servlet/ch18.controller.MessageController?message=name
(1) 컨트롤러인 MessageController.java
- package ch18.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MessageController extends HttpServlet {
public void doGet(HttpServletRequest request, - //1단계 : 사용자의 요청을 받는 서비스 메소드
HttpServletResponse response)
throws ServletException, IOException {
requestPro(request, response);
}
public void doPost(HttpServletRequest request, - //1단계 : 사용자의 요청을 받는 서비스 메소드
HttpServletResponse response)
throws ServletException, IOException {
requestPro(request, response);
}
private void requestPro(HttpServletRequest request,
HttpServletResponse response)
throws ServletException ,IOException{
String message = request.getParameter("message"); - //2단계 : 사용자의 요청분석
Object result = null;
if (message == null || message.equals("base")) { - //3단계 : 사용자의 요청에 따른 작업처리
result = "하하하.";
} else if (message.equals("name")) {
result = "홍길동 입니다.";
} else {
result = "타입이 맞지 않습니다.";
}
request.setAttribute("result", result); - //4단계 : request의 속성에 처리결과 저장
//5단계 : RequestDispatcher를 사용하여 해당 뷰로 포워딩
RequestDispatcher dispatcher =
request.getRequestDispatcher("/ch18/messageView.jsp");
dispatcher.forward(request, response);
}
}
(2) messageView.jsp
- <%@ page contentType = "text/html; charset=euc-kr" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>간단한 컨트롤러(Controller)의 사용 예제</title>
</head>
<body>
결과:
<c:set var="result" value="${requestScope.result}" />
<c:out value="${result}"/>
</body>
</html>
3. command pattern
1) 컨트롤러인 서블릿에 사용자의 명령을 전달하는 방법
(1) 요청 파라미터로 명령어를 전달하는 방법
(2) 요청 URI 자체를 명령어로 사용하는 방법
2) 요청 파라미터로 명령어 전달
(1) 명령어와 명령어 처리 클래스를 매핑한 정보파일 Commnad.properties 파일 작성
(study\WEB-INF)
Message=ch18.controller.MessageProcess
(2) 명령어 처리 클래스의 수퍼 인터페이스인 CommandProcess.java 파일 작성
- package ch18.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//요청 파라미터로 명령어를 전달하는 방식의 슈퍼 인터페이스
public interface CommandProcess {
public String requestPro(HttpServletRequest request, HttpServletResponse response)
throws Throwable;
}
(3) CommandProcess 인터페이스 구현하는 명령어 처리 클래스 MessageProcess.java 파일 작성
- package ch18.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//Controller로 부터 작업의 처리를 지시받아서 작업을 처리
public class MessageProcess implements CommandProcess {
public String requestPro(HttpServletRequest request, - HttpServletResponse response)
throws Throwable {
request.setAttribute("message", "요청 파라미터로 명령어를 전달");
return "/ch18/process.jsp";
}
}
(4) 컨트롤러인 Controller.java 파일
- package ch18.controller;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Controller extends HttpServlet {
private Map commandMap = new HashMap(); - // properties파일의 내용 중 key → 명령어 value → 클래스의 인스턴스를 기억
public void init(ServletConfig config) throws ServletException {
String props = config.getInitParameter("propertyConfig"); - //web.xml에서 propertyConfig에 해당하는 init-param 의 값을 읽어옴
Properties pr = new Properties(); - //Command.properties파일에서 명령어와 처리클래스의 매핑정보를 저장할 Properties객체 생성(key→명령어 value→처리클래스)
FileInputStream f = null;
try {
f = new FileInputStream(props); - //Command.properties파일의 객체 생성
pr.load(f);//Command.properties파일의 정보를 Properties객체에 저장
} catch (IOException e) {
throw new ServletException(e);
} finally {
if (f!=null) try { f.close(); } catch(IOException ex) {}
}
Iterator keyIter = pr.keySet().iterator(); - //Iterator객체는 Enumeration객체를 확장시킨 개념의 객체
while( keyIter.hasNext() ) { - //객체를 하나씩 꺼내서 그 객체명으로 Properties객체에 저장된 객체에 접근
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 (ClassNotFoundException e) {
throw new ServletException(e);
} catch (InstantiationException e) {
throw new ServletException(e);
} catch (IllegalAccessException e) {
throw new ServletException(e);
}
}
}
public void doGet(//get방식의 서비스 메소드
HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestPro(request, response);
}
protected void doPost(//post방식의 서비스 메소드
HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestPro(request, response);
}
//시용자의 요청을 분석해서 해당 작업을 처리
private void requestPro(HttpServletRequest request, - HttpServletResponse response)
throws ServletException, IOException {
String view = null;
CommandProcess com=null;
try {
String command = request.getParameter("command");
com = (CommandProcess)commandMap.get(command);
view = com.requestPro(request, response);
} catch(Throwable e) {
throw new ServletException(e);
}
RequestDispatcher dispatcher =request.getRequestDispatcher(view);
dispatcher.forward(request, response);
}
}
(5) web.xml(study\WEB-INF)에 추가
- <servlet>
<servlet-name>Controller</servlet-name>
<servlet-class>ch18.controller.Controller</servlet-class>
<init-param>
<param-name>propertyConfig</param-name>
<param-value>C:/work/workspace/jspStudy/WebContent/WEB-INF/Command.properties</param-value>
</init-param>
</servlet>
:
<servlet-mapping>
<servlet-name>Controller</servlet-name>
<url-pattern>/Controller</url-pattern>
</servlet-mapping>
(6) 컨트롤러가 응답결과를 보낼 process.jsp 작성
- <%@ page contentType = "text/html; charset=euc-kr" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>요청 파라미터로 명령어를 전달하는 예제</title>
</head>
<body>
처리 결과:
<c:set var="message" value="${requestScope.message}" />
<c:out value="${message}"/>
</body>
</html>
(실습) 다음과 같이 결과가 나오도록 프로그램 작성
http://localhost:8070/studyProject/Controller?command=study
처리결과 : 열심히 공부하자
http://localhost:8070/studyProject/Controller?command=play
처리결과 : 신나게 놀아보자
3) 요청 URI 자체를 명령어로 사용하는 방법
http://127.0.0.1:8080/study/ch18/message.do
(1) 명령어와 명령어 처리 클래스를 매핑한 정보 파일인 CommandURI.properties 작성
/ch18/message.do=ch18.controller.MessageProcess
(2) 명령어 처리 클래스의 슈퍼 인터페이스 CommandProcess.java(작성된 것 그대로 사용)
(3) CommandProcess 인터페이스 구현하는 명령어 처리 클래스 MessageProcess.java
(작성된 것 그대로 사용)
(4) 컨트롤러 ControllerURI
- package ch18.controller;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ControllerURI extends HttpServlet {
private Map commandMap = new HashMap();//명령어와 명령어 처리 클래스 객체 인스턴스를 쌍으로 저장
//명령어와 처리클래스 객체 인스턴스가 매핑되어 있는 properties 파일을 읽어서 Map객체인 commandMap에 저장
// properties 파일은 CommandURI.properties파일
public void init(ServletConfig config) throws ServletException {
String props = config.getInitParameter("propertyConfig");//web.xml에서 propertyConfig에 해당하는 init-param 의 값을 읽어옴
Properties pr = new Properties();//명령어와 처리클래스의 매핑정보를 저장할 Properties객체 생성
FileInputStream f = null;
try {
f = new FileInputStream(props); //Command.properties파일의 내용을 읽어옴
pr.load(f);//Command.properties파일의 정보를 Properties객체에 저장
} catch (IOException e) {
throw new ServletException(e);
} finally {
if (f != null) try { f.close(); } catch(IOException ex) {}
}
Iterator keyIter = pr.keySet().iterator();//Iterator객체는 Enumeration객체를 확장시킨 개념의 객체
while( keyIter.hasNext() ) {//객체를 하나씩 꺼내서 그 객체명으로 Properties객체에 저장된 객체에 접근
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 (ClassNotFoundException e) {
throw new ServletException(e);
} catch (InstantiationException e) {
throw new ServletException(e);
} catch (IllegalAccessException e) {
throw new ServletException(e);
}
}
}
public void doGet(//get방식의 서비스 메소드
HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestPro(request, response);
}
protected void doPost(//post방식의 서비스 메소드
HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
requestPro(request, response);
}
//시용자의 요청을 분석해서 해당 작업을 처리
private void requestPro(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String view = null;
CommandProcess com=null;
try {
String command = request.getRequestURI();
→ /study/ch18/message.do
if (command.indexOf(request.getContextPath()) == 0) {
→ /study
command = command.substring(request.getContextPath().length());
→/ch18/message.do
}
com = (CommandProcess)commandMap.get(command);
view = com.requestPro(request, response);
} catch(Throwable e) {
throw new ServletException(e);
}
RequestDispatcher dispatcher =request.getRequestDispatcher(view);
dispatcher.forward(request, response);
}
}
(5) web.xml
<servlet>
<servlet-name>ControllerURI</servlet-name>
<servlet-class>ch18.controller.ControllerURI</servlet-class>
<init-param>
<param-name>propertyConfig</param-name>
<param-value>D:/apache-tomcat-5.5.15/webapps/study/WEB-INF/CommandURI.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ControllerURI</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
(6) 컨트롤러 응답 결과 process.jsp (기존 작성)
- <%@ page contentType = "text/html; charset=euc-kr" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>요청 파라미터로 명령어를 전달하는 예제</title>
</head>
<body>
처리 결과:
<c:set var="message" value="${requestScope.message}" />
<c:out value="${message}"/>
</body>
</html>
