위로 아래

컨트롤러 설정

컨트롤러로 서블릿을 사용하며, 해쉬맵 방식을 채택한다.

key: 주소, value: 클래스로 이루어진 Command.properties 파일을 만들고, 

 

 

 

다형성 준비

다형성을 활용하기 위해 모든 비즈니스 로직 클래스의 타입을 책임질 CommandAction 인터페이스를 작성한다.

package action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface CommandAction {

	public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Exception;
	//추상 메소드
}

 

 

 

web.xml에 Servlet 설정

Controller 서블릿을 설정하고,

propertyConfig 파라미터에는, Command.properties 파일의 위치를 넣고

Controller 파라미터에는 *.do를 넣는다.

<servlet>
    <servlet-name>Controller</servlet-name>
    <servlet-class>control.Controller</servlet-class>
    <init-param>
        <param-name>propertyConfig</param-name>
        <param-value>D:/Ecom_Work_js/EcomWorkspace/javaBoard/src/main/webapp/WEB-INF/Command.properties</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>Controller</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

<init-param> : 서블릿 초기화시 넘겨 받을 값 설정

<param-name> : 파라미터 키

<param-value> : 파라미터 값

 

 

 

 

컨트롤러 서블릿 작성

 

주소를 담당하는 String과 이동할 클래스를 담당하는 부모 타입 CommandAction을 제네릭 타입으로 삼는 해쉬맵을 생성한다.

기본형은 다음과 같다.

package control;

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 action.CommandAction;

public class Controller extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
	
	private Map<String, CommandAction> commandMap = new HashMap<String, CommandAction>();
	
	@Override
	public void init(ServletConfig config) throws ServletException{
	
			...
    
	}
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
			...
        
	}
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}

 

맨 위에 해쉬맵 변수가 선언되어 있다.

private Map<String, CommandAction> commandMap = new HashMap<String, CommandAction>();

 

 

 

properties 파일 생성

WEB-INF 폴더에 Command.properies 파일 생성. 

문서 내에 key 주소 list.do, value 클래스 action.ListAction을 준다.

/list.do=action.ListAction

 

 

 

 

서블릿 초기화 메소드인 init() 작성

props 문자열에는 web.xml로부터 파라미터를 읽어와 Command.properties 파일의 주소를 불러온다. 

properties 객체를 생성한 후, 입출력 IO 클래스를 통해 읽어 온 Command.properties를 실행한다. 

public void init(ServletConfig config) throws ServletException{

    String props = config.getInitParameter("propertyConfig");
    Properties pr = new Properties();
    BufferedInputStream bf = null;

    try {
        System.out.println("===>" + props);
        bf = new BufferedInputStream(new FileInputStream(props));
        pr.load(bf);
    } catch (IOException e){
        e.printStackTrace();
        throw new ServletException(e);
    } finally {
        if(bf != null) try {bf.close();} catch( IOException ex) {};
    }
}

 

 

Command.properties에서 가져온 key들을 Iterator를 통해 순회한다.

각각의 key는 command 문자열에,

key에 해당하는 value는 classNm(클래스네임) 문자열에 저장한다.

 

classNm에 들어 있는 요소들은 단순히 클래스의 이름이니, 이를 실제 클래스로 바꿔주는 작업을 거쳐야 한다.

클래스 이름을 Class.forName()을 통해 타입이 정해지지 않은 comClass 변수에 넣는다.

사용할 클래스들의 부모 클래스 타입인 CommandAction 객체를 생성하고, 타입을 모르는 comClass 클래스를 넣고 객체를 생성한다.

 

처음에 선언해준 해쉬맵 commandMap에 주소가 되는 key값인 command를, 클래스로 바꿔준 commInstance를 넣어준다.

Iterator<Object> keyIter = pr.keySet().iterator();

while(keyIter.hasNext()){
    String command = (String)keyIter.next();
    String classNm = pr.getProperty(command);

    try {
        //String 타입으로 들어가 있는 클래스 이름 classNm을 실제 클래스로 바꿔주는 작업을 해야한다
        Class<?> comClass = Class.forName(classNm);

        @SuppressWarnings("deprecation")
        CommandAction commInstance = (CommandAction) comClass.newInstance();
        //hash맵 저장
        commandMap.put(command, commInstance);

    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
};

 

 

 

doGet 메소드 작성

@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		...
	}

doGet 메소드에서는

command 문자열에 서블릿에 들어온 주소의 앞부분을 자르고 뒤의 주소만 남길 것이다.

CommandAction 타입의 com 변수에(다형성) 위에서 만들어놓았던 해쉬맵을 이용해 command를 키로 넣으면 나오는 값을 대입한다.

그러면 해당 주소에 맞는 CommandAction의 구현클래스 객체가 형성되는데, 

이들 각자의 requestPro 메소드 결과인 문자열을 view에 대입한다. 

RequestDispatcher를 이용해 view로 forward한다.

 

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String view = null;
    CommandAction com = null;

    try {
        String command = request.getRequestURI();
        if(command.indexOf(request.getContextPath())==0) {
            command = command.substring(request.getContextPath().length());
        }
        com = commandMap.get(command);
        view = com.requestProc(request, response);
    } catch(Exception e){
        e.printStackTrace();	
    }

    RequestDispatcher dp = request.getRequestDispatcher(view);
    dp.forward(request, response);
}

 

이로써 컨트롤러 역할을 하는 서블릿이 완성되었다.

 

 

 

 

 

 


전체 코드

더보기
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
--><!-- The contents of this file will be loaded for each web application --><Context>

    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    <Resource auth="Container" 
      name="jdbc/JavaBoard" 
      driverClassName="com.mysql.jdbc.Driver" 
      type="javax.sql.DataSource" 
      url="jdbc:mysql://localhost/테이블 이름" 
      username="아이디"
      password="비밀번호" 
      loginTimeout="10" 
      maxActive="50" 
      maxIdle="20"
      maxWait="5000" 
      testOnBorrow="true" />

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
</Context>
// control.Controller
package control;

import java.io.*;
import java.util.*;

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 action.CommandAction;

public class Controller extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
	
	private Map<String, CommandAction> commandMap = new HashMap<String, CommandAction>();
	
	@Override
	public void init(ServletConfig config) throws ServletException{
		//초기화 메소드
		//Servlet이 만들어질 때 실행.
		//한 번만 실행된다.
		//properties로부터 키와 클래스 이름을 받아서 그걸 객체로 만들고 hashmap에 저장해둔다.
		//doGet(), doPost()가 실행될 때 해당 action을 실행하게 키로 만들어 둘 것.
		
		String props = config.getInitParameter("propertyConfig");
		Properties pr = new Properties();
		BufferedInputStream bf = null;

		try {
			System.out.println("===>" + props);
			bf = new BufferedInputStream(new FileInputStream(props));
			pr.load(bf);
		} catch (IOException e){
			e.printStackTrace();
			throw new ServletException(e);
		} finally {
			if(bf != null) try {bf.close();} catch( IOException ex) {};
		}
		
		Iterator<Object> keyIter = pr.keySet().iterator();
		//property에 있는 내용을 모두 읽어서 키와 값으로 가져오는데, 값은 클래스 이름
		
		while(keyIter.hasNext()){
			String command = (String)keyIter.next();
			String classNm = pr.getProperty(command);
			
			try {
				//String 타입으로 들어가 있는 클래스 이름 classNm을 실제 클래스로 바꿔주는 작업을 해야한다
				Class<?> comClass = Class.forName(classNm);
				
				@SuppressWarnings("deprecation")
				CommandAction commInstance = (CommandAction) comClass.newInstance();
				//hash맵 저장
				commandMap.put(command, commInstance);
				
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		};
	}
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String view = null;
		CommandAction com = null;
		// 주소에 해당되는 action이 들어오는 것을 받기 위한 코드
		// list.do라고 치면 localhost:8080/javaBoard/list.do 에서 앞부분을 자르고 list.do만 남길 것.
		
		try {
			String command = request.getRequestURI();
			if(command.indexOf(request.getContextPath())==0) {
				command=command.substring(request.getContextPath().length());
			}
			com = commandMap.get(command);   // 해당되는 클래스로 만들어진 VommandAction의 하위
			// 해당 CommandAction 하위 클래스를 가져와서 requestPro라는 메소드 실행
			view = com.requestPro(request, response);
			//view 화면은 나중에 화면에 뜨는 페이지 이름이 된다.
		} catch(Exception e) {
			throw new ServletException(e);
		}
		
		RequestDispatcher dp = request.getRequestDispatcher(view);
		dp.forward(request, response);
	}
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}
//action.CommandAction.interface

package action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface CommandAction {

	public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Exception;
	//추상 메소드
}