티스토리 뷰

직전에 포스팅한 Action 객체를 이용하여 프로젝트를 구성하는 MVC패턴을 사용한 예제이다.

예제 프로젝트는 게시글을 등록할 때, 비밀번호를 같이 기입하고, 해당 비밀번호를 기억하고 있어야만 게시글의 수정과 삭제가 가능한 간단한 게시판을 구현한다. 


완성 페이지의 모습은 이와 같다.





프로젝트는 다음과 같이 구성된다.

 

 1. request로 command 값을 받아서 어떤 기능을 처리할 지 판단하는 Controller

   1) 요청을 받은 1개의 유일한 Servlet

   2) 요청받은 command를 확인하고, 이에 따른 기능 객체를 생성하는 Factory

 2. 실질적인 기능을 수행하는 일반 Class 집합, Actions

   1) request, response 인자를 받는 execute 메서드를 구현한 Action 인터페이스

   2) Action 인터페이스를 구현받아 실제 기능을 작성할 일반 Class들

 3. DB와 관련된 메서드의 집합, DAO

 4. 데이터 집합을 관리할 DTO

 5.  Web Contents

 

즉, 다음과 같은 파일 구조를 가진다.


MVC 패턴의 가장 핵심적인 부분만 예시로 설명하자면, 

우선 jsp에서 보내는 모든 요청은 전부 controller의 BoardServlet.java가 처리한다.

 

◎BoardServlet.java

package com.choonham.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.choonham.controller.action.Action;

@WebServlet("/BoardServlet")
public class BoardServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String command = request.getParameter("command");

		ActionFactory factory = ActionFactory.getInstance();

		Action action = factory.getAction(command);

		if (action != null) {
			action.execute(request, response);
		}

	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		doGet(request, response);
	}

}

보면 ActionFactory 객체를 생성하여 Command값을 전달하는 역할이 전부인 간단한 Servlet이다. 

이렇게 한개의 Servlet만 사용하여 기능을 분리한다면, forward를 마구잡이로 사용하더라도 url이 꼬이는 그런 정신 나간 상황을 안 겪어도 된다. ( 2주만 더 빨리 알았더라면.... ㅂㄷㅂㄷ)

 

◎ ActionFactory.java

package com.choonham.controller;

import com.choonham.controller.action.Action;
import com.choonham.controller.action.BoardCheckPassAction;
import com.choonham.controller.action.BoardCheckPassFormAction;
import com.choonham.controller.action.BoardDeleteAction;
import com.choonham.controller.action.BoardListAction;
import com.choonham.controller.action.BoardUpdateAction;
import com.choonham.controller.action.BoardUpdateFormAction;
import com.choonham.controller.action.BoardViewAction;
import com.choonham.controller.action.BoardWriteAction;
import com.choonham.controller.action.BoardWriteFormAction;

public class ActionFactory {

	private static ActionFactory instance = null;
	
	public ActionFactory() {
	}
	
	public static ActionFactory getInstance() {
		if(instance == null) {
			instance = new ActionFactory();
		}
		return instance;
	}
	
	public Action getAction(String command) {
		Action action = null;
		
		if(command.equals("board_list")) {
			action = new BoardListAction();
		} else if(command.equals("board_write_form")) {
			action = new BoardWriteFormAction();
		} else if(command.equals("board_write")) {
			action = new BoardWriteAction();
		} else if(command.equals("board_view")) {
			action = new BoardViewAction();
		} else if(command.equals("board_check_pass_form")) {
			action = new BoardCheckPassFormAction();
		} else if(command.equals("board_check_pass")) {
			action = new BoardCheckPassAction();
		} else if(command.equals("board_update_form")) {
			action = new BoardUpdateFormAction();
		} else if(command.equals("board_delete")) {
			action = new BoardDeleteAction();
		} else if(command.equals("board_update")) {
			action = new BoardUpdateAction();
		}
		return action;
	}

}

ActionFactory는 말 그대로 인자로 받은 command 값에 따라 알맞는 클래스 객체를 생성하여 내보내주는 공장의 역할을 한다. 

 

이제 Action쪽에서 

◎ Action.java (interface)

package com.choonham.controller.action;

import java.io.IOException;

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

public interface Action {
	
	public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException; 

}

를 구현받은 클래스들이 DB와 연결하여 해당 동작을 수행하면 된다. 

조금 복잡해 보일지라도 프로젝트 규모가 커지면 커질수록 그냥 Servlet을 찍어내는 미친 방법보다는 1억배 정도 효율적인 방법이라고 생각한다.


 프로젝트의 Git:

https://github.com/Choonham/Choonham-2020.03.10-Spring-Class-JWEB-/tree/main/mvc_board

 

Choonham/Choonham-2020.03.10-Spring-Class-JWEB-

Contribute to Choonham/Choonham-2020.03.10-Spring-Class-JWEB- development by creating an account on GitHub.

github.com

 

Comments