MVC 직접제작 02

MVC 직접제작 02

 

이것이 스프링을 배우기 위한 초석이 된다.

 

작성 순서는 모델 -> 컨트롤러 -> 뷰 순이다.

web.xml

<?xml version=”1.0″ encoding=”UTF-8″?>
<web-app xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns=”http://java.sun.com/xml/ns/javaee” xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd” id=”WebApp_ID” version=”3.0″>
  <display-name>MVCProject</display-name>

  <servlet>
      <servlet-name>mvc</servlet-name>
      <servlet-class>com.controller.DispatcherServlet</servlet-class>
  </servlet>

  <servlet-mapping>
      <servlet-name>mvc</servlet-name>
      <url-pattern>*.do</url-pattern>
  </servlet-mapping>
  

  <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>
</web-app>

 

web.xml에 (1)서블릿과 (2)서블릿-매핑을 추가한다.

(1) 서블릿에는 디스패처서블릿을 등록해준다. 디스패처서블릿은 컨트롤러를 연결한다. 

서블릿-매핑은 확장자를 준다. 나중에 파일명을 쉽게 자를 수 있다. 예를 들어서, 주소가 localhost/…/list.do 면 list를 키로 넘겨주고 키값(모델)을 쉽게 가져올 수 있다. 서블릿-매핑은 .do파일을 부르면 호출한다.

 

1. 모델 만들기

com.model 패키지에 만든다.

Model.java

우선 인터페이스를 만들어둔다. 인터페이스는 일종의 추상클래스이다. Model 인터페이스를 만들고, 다른 모델들에 임플리먼츠(구현)할 수 있다.

package com.model;

import javax.servlet.http.HttpServletRequest;

public interface Model {
      public String handlerRequest(HttpServletRequest req)
      throws Exception;
}

 

ListModel.java

package com.model;

import javax.servlet.http.HttpServletRequest;

public class ListModel implements Model{

     @Override
     public String handlerRequest(HttpServletRequest req) throws Exception {
         // TODO Auto-generated method stub
         String str=”리스트모델(Model)에서 jsp로 보냅니다”;
       req.setAttribute(“msg”, str);

         return “view/list.jsp”;//’에이치티티피 서블렛 리퀘스트(req)’에 값을 실어서 list.jsp라는 스트링을 반환한다.
      }

}

 

바로 위에 만든 인터페이스 ‘모델’을 임플리먼츠(구현)하고, “핸들러 리퀘스트”를 오버라이딩한다.

핸들러 리퀘스트는 말 그대로 리퀘스트를 다룬다. 자세히 말하면, (1)”HTTP서블렛리퀘스트”의 어트리뷰트를 채워넣고, (2)결과가 출력될 jsp를 던져준다.

“핸들러 리퀘스트”의 매개변수는 ‘HTTP서블렛 리퀘스트’다. 이 ‘HTTP서블렛 리퀘스트’에 “msg”라는 이름으로 스트링을 싣는다.

 

이때, “핸들러 리퀘스트”의 반환형은 String이다. jsp파일의 경로를 적으면, 경로가 스트링값으로 반환될 것이다. 

ContentModel.java

package com.model;

import javax.servlet.http.HttpServletRequest;

public class ContentModel implements Model{

     @Override
     public String handlerRequest(HttpServletRequest req) throws Exception {
          // TODO Auto-generated method stub
          String msg=”ContentModel에서 content.jsp로 보냅니다”;
          req.setAttribute(“msg”, msg);
      return “view/content.jsp”;//req라는 리퀘스트를 뷰가 있는곳의 list.jsp로 값을 보낸다
      }

}

 

위의 ListModel.java와 동일하게 이해하면 된다. 동일하게 돌아간다.

 

2. 컨트롤러 만들기

com.controller 패키지에 만든다.

 

DispatcherServlet.java

package com.controller;

 

import java.io.*; //출력을 위한 것
import java.util.HashMap; //맵
import java.util.Map; //맵

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 com.model.*;

 

public class DispatcherServlet extends HttpServlet {
     // <선언부>

     // 버젼 선언​

     private static final long serialVersionUID = 1L;
     

     // 배열 선언
     private String[] strCmd={“list”,”content”}; //id의 배열
     private String[] strCls={“com.model.ListModel”,”com.model.ContentModel”}; //모델: 클래스의 배열
     private String[] strJsp={“view/list.jsp”,”view/content.jsp”}; //뷰: jsp의 배열
                   // 보통은 배열로 선언하지 않고, 맵에다 뿌린다.

                   //​  예를 들어 ?cmd=list 라고 사용자가 요청했다면 아래와 같이  매칭.
                   // <bean id=”list” class=”com.model.ListModel” jsp=”view/list.jsp”/>식으로 갯수만큼 써서
                   // 맵에다 넣어놨다가 뿌려주면 빠르고 간편하다.

    

     // 맵 선언
     private Map clsMap=new HashMap(); //모델(클래스)을 담는 맵
     private Map jspMap=new HashMap(); //뷰(jsp)를 담는 맵

     public void init(ServletConfig config) throws ServletException {
     // 이유는 모르겠지만 생성자 대신 init을 쓴다.

     // 객체가 만들어지자마자 모델과 뷰를 맵에 담는다.

          try{
               for(int i=0;i<strCmd.length;i++){
                    Class clsName=Class.forName(strCls[i]); //클래스를 메모리 할당

                                                                                //strCls={“com.model.ListModel”,”com.model.ContentModel”}; 
                    Object obj=clsName.newInstance(); //객체를 생성
                    clsMap.put(strCmd[i], obj); //커맨드 이름(키)에 오브젝트(키값) 대입 //id를 키로 class를 맵에 담기
                    jspMap.put(strCmd[i], strJsp[i]);    //id를 키로 jsp를 맵에 담기
                    System.out.println(strCmd[i]+”===”+obj+”===”+strJsp[i]);
                    //strCmd[i]:클라이언트의 요청값 === 오브젝트 === jsp파일 
               }
          }catch(Exception ex){System.out.println(ex.getMessage());}
     }

 

     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          doProcess(request, response);
     }

 

     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          doProcess(request, response);
     }
 
     protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          try{
               // 클라이언트가 뭘 요청했는지 알아낸다(요청값=cmd). 주소를 통해 알 수 있다.
               String cmd=request.getRequestURI();  // URI는   /MVCProject/list.do ​이다.
                                                                    //            ContextPath() 는 /MVCProject 이고,
                                                                    //            ContextPath().lengh()+1 은 /MVCProject/ 까지이다.
               cmd=cmd.substring(request.getContextPath().length()+1,cmd.lastIndexOf(“.”));

               // 서브스트링으로 자른다. 자르면, cmd 변수 에는 “list” 라는 단어 하나가 들어온다.
               Model model=(Model)clsMap.get(cmd);
               // 모델을 모아둔 클래스 맵(clsMap)을 이용해서 모델을 선언한다.
               String jsp=model.handlerRequest(request); //핸들러 리퀘스트가 반환하는 “list.jsp”라는 스트링을 저장한다.
               RequestDispatcher rd=request.getRequestDispatcher(jsp); //리퀘스트 디스패처에 jsp를 담는다.
               rd.forward(request, response);

          }catch(Exception ex){ System.out.println(ex.getMessage()); }
     }
}

 

 

3. 뷰 만들기

List.jsp

<%@ page language=”java” contentType=”text/html; charset=EUC-KR” pageEncoding=”EUC-KR”%>
<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd“>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=EUC-KR”>
<title>Insert title here</title>
</head>

<body>
         <center>${msg}</center>
</body>
</html>

 

볼 것도 없다. 그냥 표현식으로 msg 변수를 뿌려주면 된다. 달러와 중괄호 ${    } 를 표현식이라고 한다.

 

Content.jsp

<%@ page language=”java” contentType=”text/html; charset=EUC-KR” pageEncoding=”EUC-KR”%>
<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd“>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=EUC-KR”>
<title>Insert title here</title>
</head>

<body>
         <center>${msg}</center>
</body>
</html>

 

위와 똑같다.