본문 바로가기
JSP

day48) FrontController

by code_learner 2022. 3. 12.

[Controller를 서블릿을 통해 관리하는 이유]

1. JSP는 컴파일을 통해 servlet이 된다

2. 사용자(브라우저, 클라이언트)의 요청정보를 한 곳으로 모아서 분기처리가 가능하기 때문에 유지보수에 용이하다.

 

 

[FrontController]

 

* 동작순서
1. 사용자 요청
2. @WebServlet()
요청에 맞는 @가 존재하는지 확인(서블릿 "컨테이너", 톰캣이 수행해줌)
3-1. 서블릿 객체가 없다면, new 처리
3-2. new가 되어있다면 객체.메서드() 수행

 

 

1) 사용자의 모든 요청을 한곳(==FC, 서블릿)으로 모아야한다!
사용자가 (ex: *.do)요청하게 되면 @WebServlet("*.do")에 의해 FC로 오게된다

2)FC에 모든 요청처리를 작성 -> 불리
병렬개발이 어려움
오류의 파급효과가 큼
변경에 대한 재컴파일이 필수

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") // *.do로 요청하게되면 어노테이션(애너테이션)에 의해 FC로 오게된다
public class FrontController extends HttpServlet {
   private static final long serialVersionUID = 1L;
    

    public FrontController() { // 기본생성자: 서블릿 컨테이너가 관리하기위해 반드시 필요
       // 객체의 생성 및 관리를 담당하는 것==컨테이너
       // 서블릿 컨테이너==톰캣
        super();
        // TODO Auto-generated constructor stub
    }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      actionDo(request,response);
   }

   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      actionDo(request,response);
   }
   //모든 요청에 대해서 actionDo()메서드를 수행하게 요청
   
   private void actionDo(HttpServletRequest request, HttpServletResponse response) {
		String uri=request.getRequestURI();
		String cp=request.getContextPath();
		String command=uri.substring(cp.length());
		//  uri에서 *.do를 추출
     
		
		ActionForward forward=null;
		if(command.equals("/login.do")) {
			System.out.println("로그: FC: 로그인 요청");
			//request는 사용자가 넘겨준 값이 없더라도 null은 아니다.
			try {
				forward=new LoginAction().execute(request, response);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}			
		}
        else {
			System.out.println("로그: FC:잘못된 요청!");
		}
		
		if(forward==null) {//action에서 처리하는 것이아니라 일괄처리
			forward=new ActionForward();
			forward.setPath("error.jsp");
			forward.setRedirect(false);
		}
		
		// RequestDispatcher
		// : 특정 자원에 처리를 요청하고 처리 결과를 얻어오는 기능을 수행하는 클래스
		// : 사용자(브라우저,클라이언트)로부터 들어온 요청을 처리하고,
		//   그 처리 결과를 올바른 페이지(==결과를 출력하는 페이지)로 보내는 역할을 수행하는 클래스
		RequestDispatcher dispatcher=request.getRequestDispatcher(forward.getPath());
		try {
			dispatcher.forward(request, response);
			// .forward(request,response)
			// : 제어권을 넘겨서 클라이언트가 응답받을수있도록하는 메서드
			// : 요청의 처리결과로 생성되는 request,response 객체를 타겟페이지(인자)로 전달하는 메서드
		} catch (ServletException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

 


[ 요청처리를 FC로부터 분리 ]
1. 요청처리로직에 공통적으로 필요한 부분을 Action인터페이스를 이용하여 강제성 부여

package controller;

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

//모든 요청처리로직(==메서드)은
//반드시 res, req를 가져야한다!==강제
//->추상메서드=> 인터페이스
public interface Action {
	public ActionForward execute(HttpServletRequest req, HttpServletResponse res) throws Exception;
	
	//1-어디로갈지(페이지 정보)
    //2-어떻게 갈지(forward,sendRedirect)
    //어디로 어떻게 == 객체화 -> ActionForward ex)vo
}


2. output은 ActionForward 클래스에 정의

package controller;

public class ActionForward {
	private String path;//어디로 갈지
	private boolean redirect;//어떻게 갈지
	//데이터를 기본적으로 넘겨준다고 생각 (true면 데이터를 넘겨주지 않는다)
	
	public ActionForward() {	
	}

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public boolean isRedirect() {
		return redirect;
	}

	public void setRedirect(boolean redirect) {
		this.redirect = redirect;
	}	
	
}

 

3. 요청처리로직

package controller;

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

import member.MemberDAO;
import member.MemberVO;

public class LoginAction implements Action {

	@Override
	public ActionForward execute(HttpServletRequest req, HttpServletResponse res) throws Exception {

		// 1. 필터,리스너 아직 사용안함 -> 인코딩 처리
		req.setCharacterEncoding("UTF-8");
		res.setCharacterEncoding("UTF-8");

		// 2. output
		ActionForward forward=new ActionForward();

		// 3. 로직처리
		String mid=req.getParameter("mid");
		String mpw=req.getParameter("mpw");
		MemberDAO dao=new MemberDAO();
		MemberVO vo=new MemberVO();
		vo.setMid(mid);
		vo.setMpw(mpw);
		vo=dao.selectOne(vo);
		if(vo==null) {
			System.out.println("로그: 로그인 실패");
			
			forward.setPath("/a_login.jsp");
			forward.setRedirect(true);
		}
		else {
			HttpSession session=req.getSession();
			session.setAttribute("data", vo);
			
			forward.setPath("/main.do");
			forward.setRedirect(true);
		}

		return forward;
	}
}

 

 

 

 

'JSP' 카테고리의 다른 글

day47) 커스텀 태그(Custom Tag)  (0) 2022.03.14
day49) 리스너, 필터  (0) 2022.03.12
day46) JSTL  (0) 2022.03.04
day45) EL 태그  (0) 2022.03.04
day42) Scope(request, session, application)  (0) 2022.02.25

댓글