티스토리 뷰

MVC 패턴 구조

  • Model, View, Controller로 구성된다.
  • Controller는 HTTP 요청을 받아서 처리하는 역할을 한다. 요청이 오면 서비스 로직을 수행(호출)하고 응답 결과를 Model에 담는다. Controller가 비지니스 로직을 수행하기 위해 Service 단의 로직을 호출하고 응답 결과를 Model에 전달하게 된다.
  • Model은 View에 출력할 데이터를 담아두는 역할을 한다. Controller가 구현 로직을 전담하므로 Model에서는 구현 방법에 대해 몰라도 되고, View는 필요한 데이터를 Model에서 바로 가져다 사용하면 된다.
  • View는 모델에 담겨있는 데이터를 가져다가 화면을 그리는 일에 집중한다. Java 구현 코드를 넣을 필요가 없어지고 HTML에 집중할 수 있다.

정리

Servlet이 Controller의 역할을 수행하고, JSP가 View의 역할을 수행하게 된다. Model은 Request가 setAttribute(), getAttriute() 기능을 이용해서 객체를 담아놓는 역할을 수행한다.

 

요청을 받으면 먼저 서블릿이 처리하게 되고 이때 로직을 처리하고 결과를 Model에 담은 후, Dispatcher를 이용해 View를 위한 JSP로 요청을 돌리게 된다. View에서는 Model에 있는 객체를 이용해서 HTML 코드를 완성하게 된다.

회원가입 Form 서블릿

@WebServlet(name = "mvcMemberFormServlet", urlPatterns = "/servlet-mvc/members/new-form")
public class MvcMemberFormServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String viewPath = "/WEB-INF/views/new-form.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);

        dispatcher.forward(request, response);
    }
}
new-form.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="save" method="post">
    username:   <input type="text" name="username" />
    age:        <input type="text" name="age" />
    <button type="submit">전송</button>
</form>
</body>
</html>
  • 요청을 처리하는 Controller와 화면을 보여주는 View를 분리하여 만들었다.

회원저장 서블릿

@WebServlet(name = "mvcMemberSaveServlet", urlPatterns = "/servlet-mvc/members/save")
public class MvcMemberSaveServlet extends HttpServlet {

    MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String username = request.getParameter("username");
        int age = Integer.parseInt(request.getParameter("age"));

        Member member = new Member(username, age);
        memberRepository.save(member);

        // Model 에 데이터를 보관한다.
        request.setAttribute("member", member);

        // 요청을 다시 해서 다른 파일 (JSP)를 부른다. 서버 내부에서 일어나는 호출로 브라우저는 인지하지 못한다.
        String viewPath = "/WEB-INF/views/save-result.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);
    }
}
  • 요청을 받아서 처리하는 로직이 존재하고, 해당 결과를 Model에 저장하고 있다.
  • View로 요청을 돌리고 거기서 화면을 보여주게 된다.
save-result.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
성공
<ul>
    <li>id=${member.id}</li>
    <li>username=${member.username}</li>
    <li>age=${member.age}</li>
</ul>
<a href="/index.html">메인</a>
</body>
</html>
  • request.setAttribute()를 통해 저장한 객체를 사용한다. 이때 저장할 때 사용한 key를 통해 접근하여 사용할 수 있다.
  • JSP에 JAVA 코드가 들어가지 않아도 된다.

회원 목록 조회 서블릿

@WebServlet(name = "mvcMemberListServlet", value = "/servlet-mvc/members")
public class MvcMemberListServlet extends HttpServlet {

    MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        List<Member> members = memberRepository.findAll();

        // Data를 Model에 저장
        request.setAttribute("members", members);

        // View로 요청을 돌림
        String viewPath = "/WEB-INF/views/members.jsp";
        RequestDispatcher requestDispatcher = request.getRequestDispatcher(viewPath);
        requestDispatcher.forward(request, response);
    }
}
members.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<table>
    <thead>
    <th>Id</th>
    <th>User Name</th>
    <th>Age</th>
    </thead>
<c:forEach var="item" items="${members}">
    <tr>
        <td>${item.id}</td>
        <td>${item.username}</td>
        <td>${item.age}</td>
    </tr>
</c:forEach>
</table>
</body>
</html>
  • 모든 회원 목록을 조회하고 있으며 요청 처리 부분, 화면 처리 부분, 객체를 보관하는 부분이 모두 별도로 존재하고 있다. 서로 간 의존성을 분리하였다.

정리

MVC 패턴을 이용해서 역할별로 나누어 구현하였다. 이를 통해 각자 특화된 부분을 전담하여 구현할 수 있게 되었다. View에 많이 있던 Java 코드도 분리하여 작성할 수 있었고, Model에 객체를 담아서 컨트롤러와 뷰 사이에서 필요한 객체를 전달해주는 역할을 하고 있다.

하지만, Dispatcher, Request, Response, /WEB-INF/ 등 중복적인 코드가 많이 보인다는 한계점이 있다.

반응형
Comments
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday