※ MVC
Model, View, Controller의 약자로 사용자 인터페이스, 데이터 및 논리 제어를 구현하는데 널리 사용되는 소프트웨어 디자인 패턴입니다.
※ 종류
- 90년대 말 W3C 협회에서 MVC1과 MVC2 모델을 동시에 내놓았는데 그 당시에 MVC1의 패턴 방식이 더 쉬워 보여서 MVC1을 사용해왔습니다. 그러나, 웹이 점점 발전하고 페이지를 구성하는 코드의 복잡도가 높아지면서 유지보수가 어려워졌고 유지보수가 쉬운 MVC2가 현재 사용하고 있으며 MVC1은 사용하지 않고 있습니다.
1) MVC 1 모델
- JSP 와 JavaBeans만을 사용하여 웹을 개발하는 것으로 JavaBeans는 데이터베이스에 연동되는 자바의 객체를 의미합니다.
- Model의 정확한 의미는 데이터베이스 연동 로직을 제공하면서 DB에서 검색한 데이터가 제공되는 자바 객체입니다. (ex VO, DAO)
- MVC 1 구조의 핵심은 JSP인데 JSP가 Controller와 View의 기능을 모두 처리한다는 특징을 지니기 때문입니다.
※ MVC1 패턴 예시
- 로그인 화면 구성 (src/main/webapp/login.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<h1>로그인</h1>
<hr>
<form action="loginProc.jsp" method="post">
<table border="1">
<tr>
<td>아이디</td>
<td><input type="text" name="id" /></td>
</tr>
<tr>
<td>비밀번호</td>
<td><input type="password" name="password" /></td>
</tr>
<tr><td colspan="2"><input type="submit" value="로그인" /></td></tr>
</table>
</form>
</body>
</html>
- 로그인 인증 처리 ( src/main/webapp/loginProc.jsp)
<%@ page import="tommy.spring.web.user.impl.UserDAO"%>
<%@ page import="tommy.spring.web.user.UserVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
// 1. 사용자 입력 정보 추출
String id = request.getParameter("id");
String password = request.getParameter("password");
// 2. 데이터베이스 연동 처리
UserVO vo = new UserVO();
vo.setId(id);
vo.setPassword(password);
UserDAO userDAO = new UserDAO();
UserVO user = userDAO.getUser(vo);
// 3. 화면 네비게이션
if(user != null){
response.sendRedirect("getBoardList.jsp");
}else{
response.sendRedirect("login.jsp");
}
%>
- 글 목록 검색 기능 ( src/main/webapp/getBoardList.jsp)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="tommy.spring.web.board.impl.BoardDAO"%>
<%@ page import="tommy.spring.web.board.BoardVO"%>
<%@ page import="java.util.List"%>
<%
// 이렇게 view 부분과 controller 부분이 함께 있는 패턴 mvc1 패턴
// 1. 사용자 입력 정보 추출 : 검색 기능은 나중에 구현
// 2. 데이터베이스 연동 처리
BoardVO vo = new BoardVO();
BoardDAO boardDAO = new BoardDAO();
List<BoardVO> boardList = boardDAO.getBoardList(vo);
// 3. 응답 화면 구성
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Board List</title>
</head>
<body>
<h1>글 목록</h1>
<h3>테스트 회원님 환영합니다.<a href="logoutProc.jsp">Log-Out</a></h3>
<!-- 검색 시작 -->
<form action="getBoardList.jsp" method="post">
<table border="1">
<tr>
<td>
<select name="searchCondition">
<option value="TITLE">제목</option>
<option value="CONTENT">내용</option>
</select>
<input type="text" name="searchKeyword" />
<input type="submit" value="검색" />
</td>
</tr>
</table>
</form><br/>
<!-- 검색 종료 -->
<table border="1">
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>등록일</th>
<th>조회수</th>
</tr>
<%
// mvc1 패턴
for(BoardVO board: boardList){
%>
<tr>
<td><%=board.getSeq() %></td>
<td>
<a href="getBoard.jsp?seq=<%=board.getSeq() %>"><%=board.getTitle() %></a>
</td>
<td><%=board.getWriter() %></td>
<td><%=board.getRegDate() %></td>
<td><%=board.getCnt() %></td>
</tr>
<%} %>
</table><br/>
<a href="insertBoard.jsp">새글 작성</a>
</body>
</html>
※ 위의 코드 구성대로 웹을 만든다면 기능 몇가지 추가되는 순간 몇 백줄, 아니 몇 천줄이 추가 될 수 있기 때문에 한 페이지에 많은 코드가 구성된다. 이러한 구성은 후에 유지보수에 치명적이며 이에 따라 MVC2 방식으로 변화했습니다.
2) MVC 2
- MVC2의 중요 특징은 Controller의 등장으로 기존의 JSP가 담당했던 Controller 로직이 별도의 Controller 기능의 Servlet 클래스로 옮겨졌다는 것입니다.
- 기존의 MVC1에서 JSP 파일에 있는 자바 코드만 Controller로 이동하면 MVC2 패턴으로 변경 가능합니다.
※ MVC2 패턴 예시
- Controller에 해당하는 Controller Servlet 구현 ( DispatcherServlet)
package tommy.spring.web.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
processRequest(request, response);
}
private void processRequest(HttpServletRequest request, HttpServletResponse response)
throws IOException{
// 1. 클라이언트 정보를 추출한다. String uri = request.getRequestURI();
String path = uri.substring(uri.lastIndexOf("/"));
System.out.println(path);
// 2. 클라이언트의 요청 path에 따라 적절히 작업을 분기 시켜준다.
if(path.equals("/login.do")) {
System.out.println("로그인 처리");
}
}
}
- DispatcherServlet에는 Get 방식 요청을 처리하는 doGet() 메서드와 Post 방식을 처리하는 doPost() 메서드가 정의되어 있는데 어떤 방식으로 요청하든 processRequest() 메서드를 통해 처리하도록 구현하였습니다.
- Post 방식의 요청에 대해 doPost() 메서드가 수행되는데 이때 한글이 깨지지 않도록 인코딩을 UTF-8로 처리하도록 하였습니다.
- processRequest() 메서드에서는 가장 먼저 클라이언트의 요청 URI로부터 path 정보를 추출하는데 이때 추출된 path는 URI 문자열에서 마지막 “/XXX.do” 문자열입니다. 그리고 추출된 문자열에 따 라서 분기처리를 통해 해당 로직을 수행하도록 합니다.
※ 위의 MVC1 패턴의 페이지를 MVC2 패턴으로 변경
- login.jsp
<body>
<h1>로그인</h1>
<hr>
<!-- action에 해당하는 부분을 xxx.do로 변경한다. -->
<form action="login.do" method="post">
<table border="1">
<tr>
<td>아이디</td>
<td><input type="text" name="id" /></td>
</tr>
- DispatcherServlet : loginProc.jsp 내용을 넣는다.
// 위의 코드는 생략
// 2. 클라이언트의 요청 path에 따라 적절히 작업을 분기 시켜준다.
if(path.equals("/login.do")) {
System.out.println("로그인 처리");
// 1. 사용자 입력 정보 추출
String id = request.getParameter("id");
String password = request.getParameter("password");
// 2. 데이터베이스 연동 처리
UserVO vo = new UserVO();
vo.setId(id);
vo.setPasswrod(password);
UserDAO userDAO = new UserDAO();
UserVO user = userDAO.getUser(vo);
// 3. 화면 네비게이션
if(user != null){
response.sendRedirect("getBoardList.do");
}else{
response.sendRedirect("login.jsp");
}
여기서 가장 큰 변화는 View 기능의 JSP 파일인데 Controller 기능의 자바 로직을 모두 DispatcherServlet 클래스로 이동 하였습니다. 따라서 어떠한 JSP 파일에도 더 이상 자바 로직인 존재 하지 않습니다.
'Frame Work > Spring' 카테고리의 다른 글
Spring MVC (0) | 2022.10.27 |
---|---|
MVC FrameWork 구조 (0) | 2022.10.26 |
Spring Transaction (0) | 2022.10.22 |
Spring JDBC (0) | 2022.10.21 |
Spring AOP (0) | 2022.10.20 |