Web

Front Controller Pattern

kakaroo 2022. 2. 1. 20:19
반응형

article logo

 

컨트롤러가 공통 요청을 먼저 수행하고 뷰를 호출하는 패턴입니다.

프리젠테이션 레이어에 일어나는 일들의 창구로 facade 패턴의 역할과 MVC 패턴에서 controller의 역할을 함으로써 보안, 뷰 관리, 탐색들을 관리합니다.

 

  • Response 객체의 sendRedirect 메서드
  • RequestDispatcher 객체의 forward 메서드
  • 커맨드 패턴
    • 커맨드 패턴은 명령(로직)을 객체 안에 캡슐화해서 저장함으로써 컨트롤러와 같은 클래스를 수정하지 않고 재사용할 수 있게 하는 패턴.

 

1. URI parsing 해서 구현

아래 Dispatcher 역할을 하는 Servlet 에서 Front Controller 역할을 합니다.

@WebServlet("/")
public class DispatcherServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("DispatcherServlet doGet");
		
		String uri = request.getRequestURI();
		System.out.println(uri);
		
		String[] uris = uri.split("/");
		String module = uris[1];
		
		Controller controller = null;
		
		if(module.equals("add")) {
			controller = new AddController(request, response);
		} else if(module.equals("mul")) {
			controller = new MulController(request, response);
		}
		
		String rst = controller.execute();
		if(rst != null) {
			request.getRequestDispatcher(rst).forward(request, response);
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}
http://localhost:8080/mul?a=2&b=17 실행시 콘솔 출력

Controller를 uri 에 따라 나누어 줍니다.

public class AddController extends Controller{
	
	public AddController(HttpServletRequest req, HttpServletResponse res) {
		super(req, res);
	}
	
	public String execute() {
		return "/WEB-INF/add.jsp";
	}
}

public class MulController extends Controller{
	
	public MulController(HttpServletRequest req, HttpServletResponse res) {
		super(req, res);
	}
	
	public String execute() {
		return "/WEB-INF/mul.jsp";
	}
}

//Abstract 메소드를 갖는 abstract class 선언하여 기능Controller가 상속을 받아 사용하도록 한다
public abstract class Controller {
	private HttpServletRequest req;
	private HttpServletResponse res;
	
	public Controller(HttpServletRequest req, HttpServletResponse res) {
		this.req = req;
		this.res = res;
	}
	
	public abstract String execute();
}

 

2. URI 값을 map에 담아 구현

@WebServlet("/")
public class FrontController extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private Map<String, CommandHandler> commandHandlerMap = new HashMap<>();
       
    @Override
    //URI를 Key로 Handler를 Value로 HashMap을 지정한다.
    public void init() throws ServletException {
    	commandHandlerMap.put("/add", new AddHandler());
    	commandHandlerMap.put("/mul", new MulHandler());
    }
    
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    	System.out.println("요청 분석");
    	String requestURI = req.getRequestURI().toString();
    	System.out.println("요청 URI: " + requestURI);
    	
    	String command = requestURI.substring(req.getContextPath().length());
    	System.out.println("요청 command: " + command);
    	
    	CommandHandler handler = null;
    	String viewPage = null;
    	
    	if(requestURI.indexOf(req.getContextPath()) == 0) {
    		handler = commandHandlerMap.get(command);
    		viewPage = handler.handlerAction(req, res);
    		System.out.println("Model(Business Logic) 실행");
    	}
    	System.out.println("Controller가 결과 데이터를 보여줄 뷰로 포워딩");
    	req.getRequestDispatcher(viewPage).forward(req, res);
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

//http://localhost:8080/mul?a=2&b=17 실행결과
요청 분석
요청 URI: /mul
요청 command: /mul
Model(Business Logic) 실행
Controller가 결과 데이터를 보여줄 뷰로 포워딩

 

JSP 함수에서 url 주소 가져오는 다양한 함수 소개

request.getContextPath() 함수 = 프로젝트 Path만 가져옵니다.

예)  http://localhost:8080/project/list.jsp
result : /project

request.getRequestURI() 함수 = 프로젝트 + 파일경로까지 가져옵니다.
예)  http://localhost:8080/project/list.jsp
result : /project/list.jsp

request.getRequestURL() 함수 = 전체 경로를 가져옵니다.
예)  http://localhost:8080/project/list.jsp
result : http://localhost:8080/project/list.jsp

request.ServletPath() 함수 = 파일명만 가져옵니다.

예) http://localhost:8080/project/list.jsp

result : /list.jsp



public interface CommandHandler {

	public String handlerAction(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException ;

}

public class AddHandler implements CommandHandler {
	
	public String handlerAction(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {		
		int n1 = Integer.parseInt(req.getParameter("a"));
		int n2 = Integer.parseInt(req.getParameter("b"));
		
		int result = n1 + n2;
		req.setAttribute("result", result);
		return "/WEB-INF/add.jsp";
	}
}

public class MulHandler implements CommandHandler {
	
	public String handlerAction(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		int n1 = Integer.parseInt(req.getParameter("a"));
		int n2 = Integer.parseInt(req.getParameter("b"));
		
		int result = n1 * n2;
		req.setAttribute("result", result);
		return "/WEB-INF/mul.jsp";
	}
}

//add.jsp ; result를 attribute에서 받아와서 출력 또는 직접 JSP에서 결과값을 계산하여 출력
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Add</title>
</head>
<body>
<h1> Add Function</h1>
결과 : ${ result } <br>
<%
	int a = Integer.parseInt(request.getParameter("a"));
	int b = Integer.parseInt(request.getParameter("b"));
%>
<%= a %> + <%= b %> = <%= a+b %>
</body>
</html>

//mul.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Multifly</title>
</head>
<body>
<h1> Multifly Function</h1>
결과 : ${ result } <br>
<%
	int a = Integer.parseInt(request.getParameter("a"));
	int b = Integer.parseInt(request.getParameter("b"));
%>
<%= a %> * <%= b %> = <%= a*b %>

</body>
</html>

 

<실행 화면>

source : https://github.com/kakarooJ/WAS_TestProject

 

GitHub - kakarooJ/WAS_TestProject

Contribute to kakarooJ/WAS_TestProject development by creating an account on GitHub.

github.com

 

반응형