FrontController_if.ver
@WebServlet("*.hta")
public class FrontControllerServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 웹 애플리케이션의 ContextPath를 조회한다.
// ContextPath는 웹 애플리케이션을 식별하는 이름이다.
// 특별히 지정하지않으면 프로젝트이름이 contextPath가 된다.
// Tomcat에 배포된 여러 웹애플리케이션은 서로 다른 contextPath를 가지며, contextPath가 웹 애플리케이션 프로젝트를 구분하는 식별자가 된다.
String contextPath = request.getContextPath();
// 클라이언트의 요청URI를 조회한다.
String requestURI = request.getRequestURI();
requestURI = requestURI.replace(contextPath, "");
System.out.println("요청URI [" + requestURI + "]");
// 요청URI에 해당하는 컨트롤러 객체를 생성하고 실행시킨다.
try {
if ("/home.hta".equals(requestURI)) {
new HomeController().execute(request, response);
} else if ("/registerform.hta".equals(requestURI)) {
new RegisterFormController().execute(request, response);
} else if ("/register.hta".equals(requestURI)) {
new RegisterController().execute(request, response);
} else if ("/loginform.hta".equals(requestURI)) {
new LoginFormController().execute(request, response);
} else if ("/login.hta".equals(requestURI)) {
new LoginController().execute(request, response);
} else if ("/logout.hta".equals(requestURI)) {
new LogoutController().execute(request, response);
} else if ("/el1.hta".equals(requestURI)) {
new ElSampleController1().execute(request, response);
} else if ("/el2.hta".equals(requestURI)) {
new ElSampleController2().execute(request, response);
} else if ("/el3.hta".equals(requestURI)) {
new ElSampleController3().execute(request, response);
} else if ("/jstl1.hta".equals(requestURI)) {
new JstlCotroller1().execute(request, response);
} else if ("/jstl2.hta".equals(requestURI)) {
new JstlCotroller2().execute(request, response);
} else if ("/jstl3.hta".equals(requestURI)) {
new JstlCotroller3().execute(request, response);
} else if ("/jstl4.hta".equals(requestURI)) {
new JstlCotroller4().execute(request, response);
} else if ("/jstl5.hta".equals(requestURI)) {
new JstlCotroller5().execute(request, response);
}
} catch (Exception e) {
throw new ServletException(e);
}
}
}
FrontControllerServlet.java
@WebServlet("*.hta")
public class FrontControllerServlet extends HttpServlet {
private static final long serialVersionUID = 339661543186959731L;
private Map<String, Controller> controllers = new HashMap<>();
public void init() throws ServletException {
controllers.put("/home.hta", new HomeController());
controllers.put("/loginform.hta", new LoginFormController());
controllers.put("/login.hta", new LoginController());
controllers.put("/logout.hta", new LogoutController());
controllers.put("/todo/list.hta", new TodoListController());
controllers.put("/todo/detail.hta", new TodoDetailController());
controllers.put("/todo/form.hta", new TodoFormController());
controllers.put("/todo/insert.hta", new TodoInsertController());
controllers.put("/todo/update.hta", new TodoUpdateController());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String requestURI = request.getRequestURI().replace(request.getContextPath(), "");
Controller controller = controllers.get(requestURI);
if (controller == null) {
throw new RuntimeException("요청 URI에 대응되는 컨트롤러가 존재하지 않습니다.");
}
String path = controller.execute(request, response);
if (path == null) {
throw new RuntimeException("내부이동 혹은 재요청할 경로가 null입니다.");
}
if (path.startsWith("redirect:")) {
response.sendRedirect(path.replace("redirect:", ""));
} else {
path = "/WEB-INF/views/" + path;
request.getRequestDispatcher(path).forward(request, response);
}
} catch (Exception e) {
throw new ServletException(e);
}
}
}
등록,수정,삭제는 내부이동 할 필요가 없어서 재요청 URL만 보내면 됨.
왜냐하면 기능을 수행할때 보여줄 것이 없기 때문
일반 model1방식과 달라진 점은 직접 responseRedirect를 하는 것이 아니라 어디로 이동해야할 지 주소를 반환해야한다는 것.
이동하는 방법도 2가지라는 점. 1) 내부이동 2) 재요청redirect
loginController
public class LoginController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
String id = request.getParameter("id");
String password = request.getParameter("password");
User user = UserDao.getInstance().getUserById(id);
if (user == null) {
return "redirect:/model2-todo/loginform.hta?error=notfound";
}
if (!user.getPassword().equals(password)) {
return "redirect:/model2-todo/loginform.hta?error=mismatch";
}
HttpSession session = request.getSession();
session.setAttribute("loginUser", user);
return "redirect:/model2-todo/home.hta";
}
}
loginform.jsp
<div class="col-8">
<c:if test="${param.error eq 'notfound'}">
<div class="alert alert-danger mb-3">
<strong>아이디 오류</strong> 아이디에 해당하는 사용자가 존재하지 않습니다.
</div>
</c:if>
<c:if test="${param.error eq 'mismatch' }">
<div class="alert alert-danger mb-3">
<strong>비밀번호 오류</strong> 비밀번호가 일치하지 않습니다.
</div>
</c:if>
로그인폼에서 c:if로 조건걸어 error종류마다 다른 alert를 보여주기.
navbar.jsp
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item"><a class="nav-link" href="/model2-todo/home.hta">홈</a></li>
<c:if test="${not empty loginUser }">
<li class="nav-item"><a class="nav-link" href="/model2-todo/todo/list.hta">일정 목록</a></li>
<li class="nav-item"><a class="nav-link" href="/model2-todo/todo/form.hta">일정 등록</a></li>
</c:if>
</ul>
<ul class="navbar-nav">
<c:if test="${empty loginUser }">
<li class="nav-item"><a class="nav-link" href="/model2-todo/loginform.hta">로그인</a></li>
</c:if>
<c:if test="${not empty loginUser }">
<li class="nav-item"><a class="nav-link" href="/model2-todo/logout.hta"><strong>홍길동</strong>님 로그아웃</a></li>
</c:if>
</ul>
</div>
logout.jsp
public class LogoutController implements Controller {
@Override
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
/*
* 1. HttpSession객체를 획득(request.getSession())해서 session객체를 폐기(session.invalidate())시킨다.
* 2. 홈화면을 요청하는 재요청URL을 응답으로 보낸다.
*/
HttpSession session = request.getSession();
session.invalidate();
return "redirect:/model2-todo/home.hta";
}
}
화면에 뿌리게 됨.
일정목록 조회
일정목록 출력 →일정목록화면
페이징출력 →일정목록화면
————————————————————————————————————————————
todo/detail.hta?no=2&page=1 가 frontcontroller로 전달.
FrontController가 하나 생겨남 → 객체가 만들어짐. 그 안에 작은 객체도 곁다리로 들어감.
FrontController객체에는 요청파라미터 no, page가 들어있음.
execute(req,res)로 TodoDetailController로 넘어감.
TodoDetailController
todo/detail.jsp
Spring으로 가면 요청파라미터에서 값꺼내기,mybatis, db엑세스, controller를 만드는 방식이 훨씬 쉬워지고 간단해져서 로직구현해내는 것에만 집중할 수 있게 됨.