본문 바로가기
Java

[Java] MVC 프레임워크 구현

by bkuk 2023. 3. 21.

모든 클라이언트의 요청은 DispatcherServlet이 받음

  • 모든 요청을 서블릿 하나가 받을 수 있도록 URL을 매핑함.
@WebServlet( name="dispatcher", urlPatterns = "/", loadOnStartup = 1)

public class DispatcherServlet extends HttpServlet {
	[...]
}

 

Controller 인터페이스를 구현하자.

public interface Controller {
	String execute( HttpServletRequest request, HttpServletResponse response ) throws Exception;
}

 

  • excute() 메서드의 반환 값은 리다이렉트 방식으로 이동할 경우 redirect: 로 시작하고, 포워드 방식일 경우 JSP 경로를 반환
public class ListUserController implements Controller {
    private static final long serialVersionUID = 1L;
    @Override
    public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
    	if( !SessionUtils.isUserSession(request) ) {
    		return "redirect:/user/loginFrom";
    	}
    	request.setAttribute("users", DataBase.findAll());
    	return "/user/list.jsp";
    }
}

 

구현한 Controller를 요청 URL과 매핑

void initMapping() {
    mappings.put("/", new HomeController());
    mappings.put("/user/form", new ForwardController("/user/form.jsp"));
    mappings.put("/user/create", new CreateUserController());
    mappings.put("/user/list", new ListUserController());
    mappings.put("/user/loginFrom", new ForwardController("/user/login.jsp"));
    mappings.put("/user/login", new LoginController());
    mappings.put("/user/logOut", new LogOutController());
    mappings.put("/user/profile", new ProfileController());
    mappings.put("/user/updateForm", new UpdateUserFormController());
    mappings.put("/user/update", new UpdateUserController());

}

public Controller findController(String url) {
    return mappings.get(url);
}

 

  • 특별한 로직을 구현할 필요가 없는 경우에는 매번 컨트롤러를 생성하는 것이 아닌, 뷰(JSP)에 대한 이동만을 담당하는 ForwardController를 추가한다.
public class ForwardController implements Controller {
	private String forwardUrl;
	public ForwardController( String forwardUrl ) {
		this.forwardUrl = forwardUrl;
	}
	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		return forwardUrl;
	}
}

 

 

DispatcherServlet 구현

  • DispatcherServlet에서 요청 URL에 해당하는 Controller를 찾아 execute() 메서드를 호출해 실질적인 작업을 위임
@WebServlet( name="dispatcher", urlPatterns = "/", loadOnStartup = 1)
public class DispatcherServlet extends HttpServlet {
	
	private static final long seriaVersionUID = 1L;
	private static final Logger log = LoggerFactory.getLogger(DispatcherServlet.class);
	private static final String default_redirect_prifix = "redirect:";
	
	private RequestMapping rm;
    
	[..생략..]
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String requestUrl = req.getRequestURI();
		log.debug("Method : {}, Request URI : {}", 
				req.getMethod(), requestUrl);
		Controller controller = rm.findController(requestUrl);
		try {
			String viewName = controller.execute(req, resp);
			if( viewName.startsWith(default_redirect_prifix) ) {
				resp.sendRedirect(viewName.substring(default_redirect_prifix.length()));
				return;
			}
			RequestDispatcher rd = req.getRequestDispatcher(viewName);
			rd.forward(req, resp);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

댓글