스프링&스프링부트

[스프링MVC - 1편] MVC 패턴 적용, 한계

gitofjy 2025. 1. 12. 12:11

MVC 패턴 - 적용

서블릿을 컨트롤러로 사용하고, JSP 뷰로 사용해서 MVC 패턴을 적용한다

Model HttpServletRequest 객체를 사용한다

request 내부에 데이터 저장소 가지고 있는데, request.setAttribute(), request.getAttribute() 사용하면 데이터를 보관하고 조회할 있다

 

 

회원 등록 - 컨트롤러

@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);
    }
}
  • dispatcher.forward() : 다른 서블릿이나 JSP 이동할  있는 기능이며 서버 내부에서 다시 호출이 발생
  • /WEB-INF :  경로 안에 JSP 있으면 외부에서 직접 JSP 호출할  없다

 

 

회원 등록  - 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>

    <!-- 상대경로 사용, [현재 URL이 속한 계층 경로 + /save] -->
    <form action="save" method="post">
        username: <input type="text" name="username" />
        age: <input type="text" name="age" />
        <button type="submit">전송</button>
    </form>

</body>
</html>

 

 

redirect vs forward

리다이렉트는 실제 클라이언트( 브라우저) 응답이 나갔다가, 클라이언트가 redirect 경로로 다시 요청한다

따라서 클라이언트가 인지할 있고, URL 경로도 실제로 변경된다

반면에 포워드는 서버 내부에서 일어나는 호출이기 때문에 클라이언트가 전혀 인지하지 못한다

 

 

 

회원 저장 - 컨트롤러

@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);

        String viewPath = "/WEB-INF/views/save-result.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);
    }
}

HttpServletRequest Model 사용한다

request 제공하는 setAttribute() 사용하면 request 객체에 데이터를 보관해서 뷰에 전달할 있다

 

 

회원 저장 -

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="UTF-8">
</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>

 

 

회원 목록 조회 - 컨트롤러

@WebServlet(name="mvcMemberListServlet", urlPatterns="/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();

        request.setAttribute("members", members);

        String viewPath = "/WEB-INF/views/members.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);

    }
}

request 객체를 사용해서 List<Member> members 모델에 보관한다

 

 

회원 목록 조회 -

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="/index.html">메인</a>
    <table>
        <thead>
            <th>id</th>
            <th>username</th>
            <th>age</th>
        </thead>
    <tbody>
    <c:forEach var="item" items="${members}">
        <tr>
            <td>${item.id}</td>
            <td>${item.username}</td>
            <td>${item.age}</td>
        </tr>
    </c:forEach>
    </tbody>
</table>
</body>
</html>

 

 

MVC 패턴 한계

MVC 컨트롤러의 단점

  • 포워드 중복
  • ViewPath 중복
  • 사용하지 않는 코드 (예: HttpServletRequest request, HttpServletResponse response)
  • 공통처리가 어렵다 > 컨트롤러 호출 전에 먼저 공통 기능을 처리해야 한다
    • 프론트 컨트롤러(Front Controller) 패턴 도입
728x90