https://creamilk88.tistory.com/98 에서 이어지는 포스팅이다 ~
위 코드는 기존 Model2 Architecture(MVC + Singleton + FrontController pattern)을
보다 효율적은 방법으로 적용한 예제이다.
(앞선 포스팅과 Controller 부분만 수정되고, 나머지 Model (DAO, VO class) 과 Veiw(JSP) 는 동일하다.)
FrontController ( Distpatcher Sevlet )의 기능을 아래와 같이 분담한다.
request에서의 command 명령에 따라 각자의 Factory & Controller로 가서 동작한다.
Factory - Handler Mapping ( create method ) : Object를 생성하는 역할만 함
(* Distpatcher와 개별 controller의 결합도를 낮추기 위해 사용하는 역할)
[ ] Controller implements Controller (execute method) : request와 response에 대한 서비스를 제공하는 exeucte 메서드를 구현받는 각각의 객체들이 각자의 역할을 한다.
web-study 19
Controller
MVC의 Front Controller 역할을 담당
모든 클라이언트의 요청을 여기서 처리한다.
/DispatcherServlet.java
package 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;
/*
* 모든 클라이언트의 요청을 처리한다.
*/
@WebServlet("/front")
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// doGet method
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// handleRequest method 호출
this.handleRequest(request, response);
}
// doPost method
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// POST 방식 한글 처리
request.setCharacterEncoding("utf-8");
// handleRequest method 호출
this.handleRequest(request, response);
}
/*
* handleRequest method 모든 클라이언트의 요청을 처리
*/
protected void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
String command = request.getParameter("command");
Controller controller = HandlerMapping.getInstance().create(command);
String url = controller.execute(request, response).trim();
//View로 화면 전송 (방법 선택)
if (url.startsWith("redirect:")) { //redirect 방법이면 url 재할당
url = url.substring(9);
response.sendRedirect(url);
} else { //forward 방식으로 전송
request.getRequestDispatcher(url).forward(request, response);;
}
} catch (Exception e) {
e.printStackTrace();
response.sendRedirect("error.jsp");
}
}// method
}// class
개별 컨트롤러 객체 생성을 전담하는 팩토리 클래스
-> 생성은 한번만 !
-> request에 따른 command에 따라 각자의 역할을 가지고 있는 controller를 생성하여,
dispactherServlet에서 그에 맞는 controller의 execute를 사용할 수 있는 환경을 만들어준다.
/ HandlerMapping.java
package controller;
/*
* 개별 컨트롤러 객체 생성을 전담하는 팩토리 클래스
* -> 생성은 한번만 !
* */
public class HandlerMapping {
private static HandlerMapping instance = new HandlerMapping();
private HandlerMapping() { }
public static HandlerMapping getInstance() {
return instance;
}
//create(command) method
public Controller create(String command) {
Controller c= null;
if (command.contentEquals("selectCar"))
c = new SelectCarController();
else if (command.contains("registerCar"))
c = new RegisterCarController();
else if (command.contains("deleteCar"))
c = new DeleteCarController();
return c;
}
}
D
<<interface>>
개별 컨트롤러 로직을 담당하는 객체들이 구현해야하는 interface
: 사용하는 측에게 단일한 방법으로 개별 Controller 객체들이 실행되도록 표준화하는 역할을 함
: 하위 구현체들이 execute()를 overring하여 사용할 수 있게 해줌
/controller.java
package controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
* 개별 컨트롤러 로직을 담당하는 객체들이 구현해야하는 interface
* : 사용하는 측에게 단일한 방법으로 개별 Controller 객체들이 실행되도록
* 표준화하는 역할을 함
*/
public interface Controller {
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception;
}
webstudy18에서 SelectCarByIdServlet이 수정된 예제이다.
controller interface를 implements한다.
/SelectCarController.java
package controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import model.CarVO;
import model.MockDAO;
public class SelectCarController implements Controller {
@Override
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String url = null;
String id = request.getParameter("carId");
CarVO vo = MockDAO.getInstance().selectCarById(id);
if(vo == null) {
url = "selectcar-fail.jsp";
} else {
url = "selectcar-ok.jsp";
request.setAttribute("vo", vo);
}
return url;
}
}
webstudy18에서 RegisterCarController이 수정된 예제이다.
controller interface를 implements한다.
/RegisterCarController.java
package controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import model.CarVO;
import model.MockDAO;
public class RegisterCarController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// register-form.jsp에서 정보 받아오기
String id = request.getParameter("carId");
String owner = request.getParameter("owner");
String model = request.getParameter("model");
String address = request.getParameter("address");
//Model와 연동
CarVO carVO = new CarVO(id, owner, model, address);
//registerCar()함수를 이용해 등록
MockDAO.getInstance().registerCar(carVO);
//View로 이동할 url return해주기
return "redirect:car-register-result.jsp";
}
}
SelectCarController를 이용해 쉽게 DeleteCarController을 생성할 수 있다.
controller interface를 implements한다.
/DeleteCarController.java
package controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import model.MockDAO;
public class DeleteCarController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// delete-form.jsp에서 정보 받아오기
String id = request.getParameter("carId");
//Model과 연동
MockDAO.getInstance().deleteCar(id);
//View로 이동할 url return 해주기
return "redirect:delete-car-result.jsp";
}
}
브라우저 결과값은 web-study17과 같다