MVC [15] FrontControllerCommandPattern

totwo·2024년 8월 26일

JSP/Servlet/JSTL

목록 보기
15/15
post-thumbnail

기능들이 늘어가면 여러 서블릿이 생겨 서버가 무겁고 커짐
그래서 하나의 서블릿에서 여러 기능을 모아서 하도록 만듦
같은 URL Mapping으로는 구분할 수 없으니 구분기호를 이용해 구분할 것이다.

기존의 jsp에서 form action들을 변경해준다.

URL Mapping을 .do로 통일해주고
구분 기호. 앞에는 전체를 지칭하는 * 애스터리스크를 넣어준다.

@WebServlet("*.do")
// . <- 구분 기호 
public class FrontController extends HttpServlet {
 
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
		System.out.println("프론트 컨트롤러 실행");
		
		// 1. Client가 요청한 전체 URL 가져오기
		String requestURL = request.getRequestURI();		
		System.out.println(requestURL);
		
		// 2. Context Path 가져오기
		String contextPath = request.getContextPath();
		System.out.println(contextPath);
        
		// 3. 요청 url만 가져오기
		String url = requestURL.substring(contextPath.length());
		System.out.println(url);
	}
}

전에 만들어놓은
Servlet
기능들 그대로 가져와서 if 문으로 묶어서 기능 구현하기

FrontController (Servlet)

		// 회원가입
		if(url.equals("/join.do")) {
			request.setCharacterEncoding("EUC-KR");
			String id = request.getParameter("id");
			String pw = request.getParameter("pw");
			String nick = request.getParameter("nick");
			  
			WMemberVO vo = new WMemberVO(id, pw, nick);
			WMemberDAO dao = new WMemberDAO();
			int cnt = dao.join(vo);
			if (cnt > 0) {
				System.out.println("회원가입 성공");
			} else {
				System.out.println("회원가입 실패");
			}
			response.sendRedirect("main.jsp");
		// 로그인
		} else if (url.equals("/login.do")) {
			String id = request.getParameter("id");
			String pw = request.getParameter("pw");
			
			WMemberVO vo = new WMemberVO(id, pw);
			WMemberDAO dao = new WMemberDAO();
			WMemberVO info = dao.login(vo);
			
			if (info != null) {
				System.out.println("로그인 성공");
				HttpSession session = request.getSession();
				session.setAttribute("info", info);
			} else {
				System.out.println("로그인 실패");
			} 
			response.sendRedirect("main.jsp");
		// 로그아웃
		} else if (url.equals("/logout.do")) {
			HttpSession session = request.getSession();
			session.invalidate();
			response.sendRedirect("main.jsp");
		// 회원정보 리스트
		} else if (url.equals("/list.do")) {
			WMemberDAO dao = new WMemberDAO(); 
			ArrayList<WMemberVO> list = dao.list(); 	
			HttpSession session = request.getSession();
			session.setAttribute("list", list);
			response.sendRedirect("list.jsp");
		} 

main.jsp에서 각각의 servlet(controller)이랑 연결되어있던 a태그들 url 수정해주기!
-> 그런데 이렇게 한 Servlet에서 모든 기능을 구현한다???
-> 객체지향언어의 의미가 맞나?
-> SOLID 원칙 중 하나인 단일 책임 원칙에 맞지 않다!

🔰 SOLID 원칙

  1. 단일 책임 원칙 - SRP (Single Responsibility Principle)
  2. 개방 폐쇄 원칙 - OCP (Open Closed Principle)
  3. 리스코프 치환 원칙 - LSP (Liskov Substitution Principle)
  4. 인터페이스 분리 원칙 - ISP (Interface Segregation Principle)
  5. 의존 역전 원칙 - DIP (Dependency Inversion Principle

Servlet(FrontController) 으로 모아줬으나 기능을 하는 건 따로 분리하여 Class로 만들어준다

JoinController (Class)

package com.controller;

import java.io.IOException;

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

import com.model.WMemberDAO;
import com.model.WMemberVO;

public class JoinController {

	public String execute(HttpServletRequest request, HttpServletResponse response) 
    	throws ServletException, IOException {
		// Servlet(FrontController)와 동일하게 가져와 throws 해주자
		
		request.setCharacterEncoding("EUC-KR");
		String id = request.getParameter("id");
		String pw = request.getParameter("pw");
		String nick = request.getParameter("nick");
		  
		WMemberVO vo = new WMemberVO(id, pw, nick);
		WMemberDAO dao = new WMemberDAO();
		int cnt = dao.join(vo);
		if (cnt > 0) {
			System.out.println("회원가입 성공");
		} else {
			System.out.println("회원가입 실패");
		}
		return "main.jsp";
	}	
}

LoginController (Class)

package com.controller;

import java.io.IOException;

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

import com.model.WMemberDAO;
import com.model.WMemberVO;

public class LoginController {
	
	public String execute(HttpServletRequest request, HttpServletResponse response) 
    	throws ServletException, IOException {
		
		String id = request.getParameter("id");
		String pw = request.getParameter("pw");
		
		WMemberVO vo = new WMemberVO(id, pw);
		WMemberDAO dao = new WMemberDAO();
		WMemberVO info = dao.login(vo);
		
		if (info != null) {
			System.out.println("로그인 성공");
			HttpSession session = request.getSession();
			session.setAttribute("info", info);
		} else {
			System.out.println("로그인 실패");
		}  
		return "main.jsp";
	}
}

LogoutController (Class)

package com.controller;

import java.io.IOException;

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

public class LogoutController {
	
	public String execute(HttpServletRequest request, HttpServletResponse response) 
    	throws ServletException, IOException {
		
		HttpSession session = request.getSession();
		session.invalidate(); 
		return "main.jsp";
	}
}

ListController (Class)

package com.controller;

import java.io.IOException;
import java.util.ArrayList;

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

import com.model.WMemberDAO;
import com.model.WMemberVO;

public class ListController {
	
	public String execute(HttpServletRequest request, HttpServletResponse response) 
    	throws ServletException, IOException {
		
		WMemberDAO dao = new WMemberDAO(); 
		ArrayList<WMemberVO> list = dao.list(); 	
		HttpSession session = request.getSession();
		session.setAttribute("list", list);
		return "list.jsp";
	}
}

FrontController (Servlet)

		// 회원가입
		if(url.equals("/join.do")) {
			JoinController command = new JoinController();
			String moveURL = command.execute(request, response);
			response.sendRedirect(moveURL);
		// 로그인
		} else if (url.equals("/login.do")) {
			LoginController command = new LoginController();
			String moveURL = command.execute(request, response);
			response.sendRedirect(moveURL);
		// 로그아웃
		} else if (url.equals("/logout.do")) {
			LogoutController command = new LogoutController();
			String moveURL = command.execute(request, response);
			response.sendRedirect(moveURL);
		// 회원정보 리스트
		} else if (url.equals("/list.do")) {
			ListController command = new ListController();
			String moveURL = command.execute(request, response);
			response.sendRedirect(moveURL);
		} 

중복되는 거 수정해주기!!

FrontController (Servlet)

		String moveURL = null;
		
		// 회원가입
		if(url.equals("/join.do")) {
			JoinController command = new JoinController();
			moveURL = command.execute(request, response);
		// 로그인
		} else if (url.equals("/login.do")) {
			LoginController command = new LoginController();
			moveURL = command.execute(request, response);
		// 로그아웃
		} else if (url.equals("/logout.do")) {
			LogoutController command = new LogoutController();
			moveURL = command.execute(request, response);
		// 회원정보 리스트
		} else if (url.equals("/list.do")) {
			ListController command = new ListController();
			moveURL = command.execute(request, response);			
		} 
		response.sendRedirect(moveURL); 

추상 메서드 (Class, Interface)를 이용하여 추상화 시키자
-> Interface를 사용하여 동일한 기능을 수행하는 것을 강제화
-> 자바의 다형성을 이용하여 유지보수성 높임
-> 코드들을 통일화하였기 때문에 확장성 좋아짐

interface Command

package com.front;

import java.io.IOException;

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

public interface Command {

	public String execute(HttpServletRequest request, HttpServletResponse response)
    	throws ServletException, IOException;
}

interface 만들어주어 Controller(class)에서 implements해주자

FrontController (Servlet)

		String moveURL = null;
		Command command = null;
		// 추상 메서드 객체 생성은 되지 않으나 담을 수 있는 변수 생성은 가능함
		
		// Command의 자식 클래스인 Controller를 Command에 넣을 수 있다. (Upcasting)
		// 이렇게 부모타입으로 자식을 참조하는 경우
		// 자식클래스에 Overring된 메소드가 있다면 부모의 메소드는 자식의 메소드로 대체된다. (Overriding)
		
		// 회원가입
		if(url.equals("/join.do")) {
			command = new JoinController();
		// 로그인
		} else if (url.equals("/login.do")) {
			command = new LoginController();
		// 로그아웃
		} else if (url.equals("/logout.do")) {
			command = new LogoutController();
		// 회원정보 리스트
		} else if (url.equals("/list.do")) {
			command = new ListController();
		// 회원정보 수정
		} else if (url.equals("/update.do")) {
			command = new UpdateController();				
		}
		moveURL = command.execute(request, response);		
		response.sendRedirect(moveURL); 

코드가 훨씬 간단해지고 유지보수 하기 좋아진다

profile
Hello, World!

0개의 댓글