학부공부/웹시스템설계및개발

Command 패턴을 알아보자.

IT grow. 2018. 10. 29. 23:20
반응형

Command 패턴 기반의 코드

 

웹 브라우저를 통해서 명령어를 전달하는 방법은 2가지

1.     특정 이름의 파라미터에 명령어 정보를 전달

2.     요청 URL 자체를 명령어로 사용

 

 

Command 패턴의 적용

 

각 요청을 처리하는 클래스를 별도로 작성한다 . 이때 요청을 하나의 커맨드로 볼 경우 , 각 커맨드를 처리하는 핸들러 클래스가 따로 존재한다

(Command 패턴)

 

커맨드와 커맨드 핸들러 클래스 사이의 매핑 정보를 별도의 파일에 저장한다.

 

Command 패턴의 적용 2

 

--> 위의 같은 경우는 CommandHandler라는 인터페이스를 하나 만들어 놓고 , 여러가지의 요청을 처리해주는 클래스를 만들어 주게 되는데 , 

CommandHandler 를 implements 로써 사용하여서 오버라이딩을 해준다 . 위에서는 process()라는 메소드를 오버라이딩을 해줄 것이다.


Command 패턴의 적용 3

 

위의 그림은 , Controller인 서블릿이 요청을 처리하는 과정을 보여준 것인데 , 여기서 중요하게 봐야할 곳은 CommandHandler가 어떻게 사용되는지 보는것이다.

우리는 CommandHandler를 사용해서 각각의 요청을 처리할 것이며 , 처리한 결과를 저장하고 , 그 결과를 뷰로써 리턴시켜 주는 것이다.


Command 패턴의 적용 4


위의 그림은 , < 명령어 , 핸들러 클래스 > 의 매핑을 그림으로 표현한 것인데 , 

쉽게 말해서 명령어와 핸들러 클래스는 Map의 구조를 띄면서 , 각 명령어에 따른 핸들러 클래스가 사용됨으로써 

요청을 처리하게 되는 것이다.


Command 선택

 

1.     요청 URI로부터 Command를 선택

2.     특정 파라미터의 값을 Command로 선택


이렇게 설명만 주구창창 써 놓으면 와닿지가 않을 것이다.

나 또한 내가 무슨 말을 하는지 모르겠다.


코드를 통해서 정확하게 어떻게 사용되는지 확인해 보자 .



먼저 , 요청 처리를 담당하는 CommandHandler 인터페이스를 만들어 줄 것이다.

패키지명은 example로 통일 시켜 줄 것이다.


CommandHandler.java 

package example;

import javax.servlet.http.HttpServletRequest; 

import javax.servlet.http.HttpServletResponse;

public interface CommandHandler { 

public String process(HttpServletRequest req, HttpServletResponse res) throws Exception; 

// Request , Response의 매개변수를 가지는 process 메소드를 가지는 인터페이스 

// 이때 process 메소드는 추상메소드의 형태를 띄게 된다.

}



ControllerUsingFile.java

package example;

import java.io.FileReader; 

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.ServletException; 

import javax.servlet.http.HttpServlet; 

import javax.servlet.http.HttpServletRequest; 

import javax.servlet.http.HttpServletResponse; 

import example.CommandHandler; 

import example.NullHandler;

public class ControllerUsingFile extends HttpServlet { // Servlet을 상속받는다

// <커맨드, 핸들러인스턴스> 매핑 정보 저장 

private Map<String, CommandHandler> commandHandlerMap = new HashMap<>();


public void init() throws ServletException {  // init : 초기화 메소드 

String configFile = getInitParameter("configFile"); 

Properties prop = new Properties(); 

String configFilePath = getServletContext().getRealPath(configFile); 

try (FileReader fis = new FileReader(configFilePath)) 

prop.load(fis); 

catch (IOException e) 

throw new ServletException(e);

Iterator keyIter = prop.keySet().iterator(); 

while (keyIter.hasNext()) 

String command = (String) keyIter.next(); 

String handlerClassName = prop.getProperty(command);

try { 

Class<?> handlerClass = Class.forName(handlerClassName); // Class<?> 는 모든 클래스를 의미한다 . 

CommandHandler handlerInstance = (CommandHandler) handlerClass.newInstance();  // CommandHandler는 인터페이스 이므로 new 사용 x 

commandHandlerMap.put(command, handlerInstance); 

catch (ClassNotFoundException | InstantiationException | 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.getParameter("cmd"); 

CommandHandler handler = commandHandlerMap.get(command); 

if (handler == null) 

handler = new NullHandler(); //404 에러 응답 

String viewPage = null; 

try { 

viewPage = handler.process(request, response); 

catch (Throwable e) 

throw new ServletException(e); 

if (viewPage != null) 

RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage); 

dispatcher.forward(request, response);  // 포워딩 부분 

}



NullHandler.java

package example;

import javax.servlet.http.HttpServletRequest; 

import javax.servlet.http.HttpServletResponse;

public class NullHandler implements CommandHandler {

@Override public String process(HttpServletRequest req, HttpServletResponse res) throws Exception 

res.sendError(HttpServletResponse.SC_NOT_FOUND); return null; }

}



web.xml // Servlet 매핑 


<?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" version="3.1">


<servlet> 

<servlet-name>ControllerUsingFile</servlet-name> 

<servlet-class>example.ControllerUsingFile</servlet-class> 

<init-param> 

<param-name>configFile</param-name> 

<param-value>/WEB-INF/commandHandler.properties</param-value> 

</init-param> 

<load-on-startup>1</load-on-startup> 

</servlet> 

<servlet-mapping> 

<servlet-name>ControllerUsingFile</servlet-name> 

<url-pattern>/controllerUsingFile</url-pattern> 

</servlet-mapping> 

</web-app>



WEB-INF/commandHandler.properties


hello=example.HelloHandler 

#someCommand=any.SomeHandler



src/example.HelloHandler.java


package example;
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import example.CommandHandler;
public class HelloHandler implements CommandHandler 
{
@Override 
public String process(HttpServletRequest req, HttpServletResponse res) 
req.setAttribute("hello", "안녕하세요!"); 
return "/WEB-INF/view/hello.jsp";
 } 
}


반응형