728x90
FrontController 패턴
FrontController는 소프트웨어 디자인 패턴 중 하나로, 웹 어플리케이션 및 다른 종류의 소프트웨어에서 사용되는 패턴입니다. FrontController는 어플리케이션의 진입점 역할을 수행하며, 클라이언트 요청을 받아들이고 해당 요청에 대한 처리 방식을 중앙에서 제어하는 컴포넌트입니다.
FrontController 특징
- 중앙 집중화된 요청 처리 : FrontController는 클라이언트로부터 들어오는 모든 요청을 중앙에서 처리합니다. 이렇게 함으로써 애플리케이션의 요청 처리 로직을 한 곳에서 관리할 수 있습니다.
- 인터셉팅과 전처리 : 클라이언트 요청이 들어올 때 FrontController는 해당 요청을 인터셉트하고 전처리 작업을 수행합니다. 이 단계에서는 인증, 권한 확인, 로깅 등과 같은 공통 작업을 처리할 수 있습니다.
- 커맨드 패턴 활용 : FrontController는 커맨드 패턴을 사용하여 요청을 처리하는데, 각 요청에 대한 구체적인 처리 로직은 커맨드 객체로 캡슐화됩니다.
- 뷰 관리 : 요청 처리가 완료되면 FrontController는 적절한 뷰를 선택하고 뷰를 렌더링하여 클라이언트에 반환합니다.
- 렌더링과 후처리 : FrontController는 뷰 렌더링 이후에도 후처리 작업을 수행할 수 있습니다. 이 단계에서는 보안 설정, 캐싱, 리소스 정리 등을 수행할 수 있습니다.
FrontController 장점
- 코드 구조의 명확화 : FrontController 패턴을 사용하면 애플리케이션의 구조가 명확해집니다. 각 커맨드 객체는 특정한 요청 처리만 담당하므로 코드의 모듈화와 재사용성이 높아집니다.
- 유지보수성 향상 : 코드 중복을 최소화하고 공통 작업을 효율적으로 처리함으로써 유지보수성이 향상됩니다. 새로운 요청 타입이나 작업을 추가하는 경우 전체 애플리케이션을 수정할 필요 없이 해당 부분만 확장할 수 있습니다.
- 비즈니스 로직과 UI 분리 : FrontController 패턴을 사용하면 비즈니스 로직과 사용자 인터페이스(UI) 처리를 분리할 수 있습니다. 이로써 애플리케이션의 관리가 더 용이해집니다.
실습
controller.jsp → FrontController.java
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.ArrayList,model.BoardVO" %>
<jsp:useBean id="bDAO" class="model.BoardDAO" />
<jsp:useBean id="mDAO" class="model.MemberDAO" />
<jsp:useBean id="mVO" class="model.MemberVO" />
<jsp:setProperty property="*" name="mVO" />
<jsp:useBean id="bVO" class="model.BoardVO" />
<jsp:setProperty property="*" name="bVO" />
<%
String action=request.getParameter("action");
System.out.println("로그: controller.jsp");
System.out.println("action: "+action);
System.out.println("bVO: "+bVO);
System.out.println("mVO: "+mVO);
if(action.equals("main")){
ArrayList<BoardVO> datas=bDAO.selectAll(null);
request.setAttribute("datas", datas);
request.getRequestDispatcher("b_main.jsp").forward(request, response);
}
else if(action.equals("board")){
bVO=bDAO.selectOne(bVO);
if(bVO!=null){
request.setAttribute("data", bVO);
request.getRequestDispatcher("d_board.jsp").forward(request, response);
}
}
else if(action.equals("login")){
mVO = mDAO.selectOne(mVO); // mVO에 mid,mpw가 setter에 의해 저장됨
if(mVO==null){
out.println("<script>alert('로그인 실패...');history.go(-1);</script>");
}
else{
session.setAttribute("mid", mVO.getMid());
response.sendRedirect("controller.jsp?action=main");
}
}
else if(action.equals("logout")){
session.removeAttribute("mid");
response.sendRedirect("controller.jsp?action=main");
}
else if(action.equals("signupPage")){
response.sendRedirect("e_signup.jsp");
}
else if(action.equals("signup")){
boolean flag=mDAO.insert(mVO);
if(flag){
out.println("<script>alert('회원가입 성공! 로그인후에 이용하세요! :D');location.href='controller.jsp?action=main';</script>");
}
else{
out.println("<script>alert('회원가입 실패...');history.go(-1);</script>");
}
}
else if(action.equals("insertBoardPage")){
response.sendRedirect("c_insertBoard.jsp");
}
else if(action.equals("insertBoard")){
boolean flag=bDAO.insert(bVO);
if(flag){
out.println("<script>alert('게시글 작성 성공!');location.href='controller.jsp?action=main';</script>");
}
else{
out.println("<script>alert('게시글 작성 실패...');history.go(-1);</script>");
}
}
else if(action.equals("updateBoard")){
boolean flag=bDAO.update(bVO);
if(flag){
out.println("<script>alert('게시글 변경 성공!');location.href='controller.jsp?action=board&num="+bVO.getNum()+"';</script>");
}
else{
out.println("<script>alert('게시글 변경 실패...');history.go(-1);</script>");
}
}
else if(action.equals("deleteBoard")){
boolean flag=bDAO.delete(bVO);
if(flag){
response.sendRedirect("controller.jsp?action=main");
}
else{
out.println("<script>alert('게시글 삭제 실패...');history.go(-1);</script>");
}
}
else if(action.equals("mypagePage")){
response.sendRedirect("mypage.jsp");
}
else if(action.equals("mypage")){
///// mVO.setMid((String)session.getAttribute("mid"));
mVO=mDAO.selectOne(mVO);
if(mVO!=null){
request.setAttribute("data", mVO);
request.getRequestDispatcher("f_mypage.jsp").forward(request, response);
}
else{
out.println("<script>alert('비밀번호 불일치...');history.go(-1);</script>");
}
}
else if(action.equals("updateMember")){
boolean flag=mDAO.update(mVO);
if(flag){
out.println("<script>alert('회원정보 변경 성공! 로그인후에 이용하세요! :D');location.href='controller.jsp?action=logout';</script>");
}
else{
out.println("<script>alert('회원정보 변경 실패...');history.go(-1);</script>");
}
}
else if(action.equals("deleteMember")){
boolean flag=mDAO.delete(mVO);
if(flag){
out.println("<script>alert('회원탈퇴 성공!');location.href='controller.jsp?action=logout';</script>");
}
else{
out.println("<script>alert('회원탈퇴 실패...');history.go(-1);</script>");
}
}
else{
out.println("<script>alert('action 파라미터의 값을 확인해주세요!');history.go(-1);</script>");
}
%>
controller.jsp
↓
package controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
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("*.do")
public class FrontController extends HttpServlet {
private static final long serialVersionUID = 1L;
public FrontController() {
super();
}
private void doAction(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. Client가 보낸 요청을 추출 -> 어떤 액션인지 파악
// 더이상 파라미터를 들고다니지않음!
// URL을 분석해야함!!!
String uri=request.getRequestURI();
System.out.println("uri: "+uri);
String cp=request.getContextPath();
System.out.println("cp: "+cp);
String command=uri.substring(cp.length());
System.out.println("command: "+command);
// 2. 추출한 요청에 맞는 Action클래스의 execute() 메서드를 호출
ActionForward forward=null;
if(command.equals("/main.do")) {
forward=new MainAction().execute(request, response);
}
else if(command.equals("/signup.do")) {
forward=new SignupAction().execute(request, response);
}
else if(command.equals("/mypage.do")) {
forward=new MypageAction().execute(request, response);
}
else if(command.equals("/login.do")) {
forward=new LoginAction().execute(request, response);
}
else if(command.equals("/logout.do")) {
forward=new LogoutAction().execute(request, response);
}
else if(command.equals("/board.do")) {
forward=new BoardAction().execute(request, response);
}
else if(command.equals("/signupPage.do")) {
forward=new ActionForward();
forward.setRedirect(true);
forward.setPath("e_signup.jsp");
}
else if(command.equals("/insertBoardPage.do")) {
forward=new ActionForward();
forward.setRedirect(true);
forward.setPath("c_insertBoard.jsp");
}
else if(command.equals("/updateBoard.do")) {
forward=new UpdateBoardAction().execute(request, response);
}
else if(command.equals("/deleteMember.do")) {
forward=new DeleteMemberAction().execute(request, response);
}
else if(command.equals("/deleteBoard.do")) {
forward=new DeleteBoardAction().execute(request, response);
}
else if(command.equals("/updateMember.do")) {
forward=new UpdateMemberAction().execute(request, response);
}
else if(command.equals("/insertBoard.do")) {
forward=new InsertBoardAction().execute(request, response);
}
else {
}
// 3. 사용자에게 응답. View로 이동
if(forward!=null) {
if(forward.isRedirect()) {
response.sendRedirect(forward.getPath());
}
else {
RequestDispatcher dispatcher=request.getRequestDispatcher(forward.getPath());
dispatcher.forward(request, response);
}
}
else {
response.sendRedirect("goback.jsp");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doAction(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doAction(request, response);
}
}
FrontController.java
Action 인터페이스 생성 후 execute() 추상메서드 정의
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Action {
ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
Action.java
ActionForward 클래스 생성
package controller;
public class ActionForward {
private boolean redirect;
private String path;
public boolean isRedirect() {
return redirect;
}
public void setRedirect(boolean redirect) {
this.redirect = redirect;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
ActionForward.java
GitHub
https://github.com/Qkrwnsgus0522/JSP
728x90