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{@Overridepublic String process(HttpServletRequest req, HttpServletResponse res){req.setAttribute("hello", "안녕하세요!");return "/WEB-INF/view/hello.jsp";}}
'학부공부 > 웹시스템설계및개발' 카테고리의 다른 글
Spring 개발환경 구축하기 (0) | 2018.11.24 |
---|---|
필터(filter)란? (0) | 2018.10.29 |
MVC 패턴 기초. (0) | 2018.10.13 |
서블릿(Servlet) 기초. (0) | 2018.10.13 |
태그 파일의 variable 디렉티브와 name-given을 이용한 변수 추가 (0) | 2018.10.13 |
#IT #먹방 #전자기기 #일상
#개발 #일상