[ MVC패턴 ]
:: Model-View-Controller
:: 컨트롤러가 요청을 받아 모델을 실행하고 컨트롤러로 돌아와 알맞은 뷰를 실행시켜 응답을 얻어 사용자에게 보내줌
[ 모델 1 구조 ]
:: JSP에서 요청 처리 및 뷰 생성을 처리하기 때문에 구현이 쉽다.
:: 코드가 섞여서 코드가 복잡해진다.
[ 모델 2 구조 ]
:: 모든 요청을 하나의 서블릿이 처리.
:: 요청 처리 후 결과를 보여줄 JSP로 이동.
※ 빈객체 :: Bean객체를 의미
º Model
:: 비즈니스 상태정보를 처리한다.
:: Class
º View
:: 비즈니스 영역에 대한 프레젠테이션 뷰(사용자가 보게 될 결과 화면)을 담당한다.
:: JSP
º Controller
:: 사용자의 입력 및 흐름제어를 담당.
:: Servlet(HttpServlet을 상속받아 사용)
[ Servlet ]
[ Model ]
º Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | package mvc; 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 SimpleController extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } private void processRequest(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { // 2단계, 요청 파악 // request 객체로부터 사용자의 요청을 파악하는 코드 -무슨타입인지 받음 String type = request.getParameter("type"); // 3단계, 요청한 기능을 수행한다. // 사용자에 요청에 따라 알맞은 코드 // type을 분석해서 처리 끝! Object resultObject = null; //어떤 타입의 객체든 다 받기 위해 odject변수 선언 if (type == null || type.equals("greeting")) { resultObject = "안녕하세요."; } else if (type.equals("date")) { resultObject = new java.util.Date(); } else { resultObject = "Invalid Type"; } // 4단계, request나 session에 처리 결과를 저장 //뷰에서 쓰기 위해 저장 필요없으면 저장하지 않아도 됨 request.setAttribute("result", resultObject); // 5단계, RequestDispatcher를 사용하여 알맞은 뷰로 포워딩 RequestDispatcher dispatcher = request.getRequestDispatcher("/simpleView.jsp"); // webcontext다음 경로 dispatcher.forward(request, response); } } |
º View
1 2 3 4 5 6 7 8 9 10 11 12 | <%@ page contentType="text/html; charset=UTF-8"%> <!DOCTYPE html> <html> <head> <title>뷰</title> </head> <body> 결과:${result} </body> </html> |
º web.xml의 Servlet
1 2 3 4 5 6 7 8 9 | <servlet> <servlet-name>SimpleController</servlet-name> <!-- servlet객체의 이름으로 아무거나 적어도 됨 --> <servlet-class>mvc.SimpleController</servlet-class> <!-- 내가 사용하려고 하는 servlet 클래스명 --> </servlet> <servlet-mapping> <servlet-name>SimpleController</servlet-name> <url-pattern>/simple</url-pattern> </servlet-mapping> |
º properties파일
1 | hello = mvc.command.HelloHandler |
[ 클라이언트의 요청 명령을 구분하는 방식 ]
1) 특정 이름의 파라미터 값을 받아와서 명령어 정보를 전달하는 방식
2) 요청 uri를 명령어로 사용하는 방식(context경로를 제외한 나머지 path를 가지고 사용)
[ 커맨드 패턴을 이용한 요청 처리 ]
:: 클라이언트의 각 요청을 처리하는 별도의 클래스를 제공하는 구현 패턴
:: 하나의 명령어를 하나의 클래스가 처리
☞ 클래스 구성
:: 명령어를 처리하는 클래스들은 동일한 인터페이스를 구현
:: 즉, 동일한 Super를 가짐( super는 인터페이스로 만들어야 함)
[ 요청 URI를 명령어로 사용시 ]
:: context root부터 0번 인덱스부터 context root의 끝 인덱스까지의 length를 구하고 context root의 끝부터 uri의 끝까지의 경로를 사용
º Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | import java.io.FileInputStream; import java.io.IOException; import java.net.URL; 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.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import mvc.command.CommandHandler; import mvc.command.NullHandler; public class ControllerUsingURI extends HttpServlet { // <커맨드, 핸들러인스턴스> 매핑 정보 저장 private Map commandHandlerMap = new java.util.HashMap(); public void init(ServletConfig config) throws ServletException { String configFile = config.getInitParameter("configFile2"); Properties prop = new Properties(); FileInputStream fis = null; try { String configFilePath = config.getServletContext().getRealPath( configFile); fis = new FileInputStream(configFilePath); prop.load(fis); } catch (IOException e) { throw new ServletException(e); } finally { if (fis != null) try { fis.close(); } catch (IOException ex) { } } Iterator keyIter = prop.keySet().iterator(); while (keyIter.hasNext()) { String command = (String) keyIter.next(); String handlerClassName = prop.getProperty(command); try { Class handlerClass = Class.forName(handlerClassName); Object handlerInstance = handlerClass.newInstance(); commandHandlerMap.put(command, handlerInstance); } catch (ClassNotFoundException e) { throw new ServletException(e); } catch (InstantiationException e) { throw new ServletException(e); } catch (IllegalAccessException e) { throw new ServletException(e); } } } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { process(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { process(request, response); } private void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String command = request.getRequestURI(); if (command.indexOf(request.getContextPath()) == 0) { command = command.substring(request.getContextPath().length()); } CommandHandler handler = (CommandHandler) commandHandlerMap.get(command); if (handler == null) { handler = new NullHandler(); } String viewPage = null; try { viewPage = handler.process(request, response); } catch (Throwable e) { throw new ServletException(e); } RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage); dispatcher.forward(request, response); } } |
º web.xml의 servlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <servlet> <servlet-name>ControllerUsingURI</servlet-name> <servlet-class>mvc.controller.ControllerUsingURI</servlet-class> <init-param> <param-name>configFile2</param-name> <param-value> /WEB-INF/commandHandlerURI.properties </param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>ControllerUsingURI</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> |
º properties파일
1 | /hello.do=mvc.command.HelloHandler |
서버 start -> 서버에 올린 project 검사 : web.xml
-> web.xml 읽는다.(서블릿 객체 생성, url 매핑)
-> url에 맞는 요청 처리 ( webcontext 를 제외한 경로)
-> 서블릿 호출
1.처음 사용시 -> 객체 생성 -> init()호출 -> doGet() || doPost()를 호출
2.이미 한번이상 사용한 경우 객체생성이나 init()호출 없이 doGet() || doPost()를 호출
doPost()
:: form에서 method를 post라고 지정하여야함
:: 나머지의 경우는 다 get방식
init() ::: properties파일로부터 정보 읽어와서
name -> key
value -> 객체 생성 후 저장
사용할 모든 모델클래스를 객체로 만들어서 저장해둔다.