Java : JSP MVC 패턴

NuyHes·2025년 8월 20일
0

[Study]

목록 보기
68/71
post-thumbnail

🕵️ MVC란

초기 웹 개발은 템플릿 안에 서버 코드를 섞어 넣는 방식이 주류였다(ASP, PHP 그리고 JSP의 스크립틀릿) 배우기 쉽고 결과가 바로 보이는 장점이 있었지만 프로젝트 규모가 클 수록 스파게티 코드로 유지보수가 어려웠다.

MVC(Model - View - Controller) : 화면, 데이터, 제어를 역할별로 분리해 개발 유지보수를 쉽게 만드는 아키텍쳐 패턴이다.

  • Model : 비즈니스 로직과 데이터(도메인, 서비스, DAO)
  • View : 사용자에게 보여줄 화면(템플릿, JSP/Thymeleaf/HTML)
  • Controller : 요청을 받아 검증/권한 확인 후 Model을 호출하고 결과를 View에 전달

Model 1 (JSP가 Controller + View)

어떻게 생겼나?

  • JSP가 요청을 직접 받고(request.getParameter), 비즈니스 호출(JavaBean/DAO) 화면 출력까지 한 페이지에서 해결한다.
  • 필요하면 RequestDispatcher.forward()로 다른 JSP로 넘겨 출력만 분리하기도 했지만 컨트롤러 역할은 여전히 JSP가 맡았다.

등장 배경

  • 당장 빠르게 화면을 만들 수 있음
  • 도구/프레임워크가 성숙하지 않았고 팀도 소규모인 경우

드러난 문제

  • 역할 혼재 : 파라미터 검증, 인증/권한, 로깅, 예외가 JSP마다 제각각
  • 중복과 스파게티화 : 페이지가 늘수록 비슷한 로직의 복붙 지옥
  • 테스트/보안/유지보수의 어려움 : 화면 바꾸다 로직이 깨지고 로직 바꾸다 화면이 깨짐

이렇게 Model1은 빠르게 만들 수 있는 장점이 있지만 규모가 커질수록 관리가 어렵다는 한계를 드러냈다.

개념

  • 요청을 JSP가 직접 받음 👉 JSP 안에서 파라미터 처리/검증/비즈니스 호출 (보통 JavaBean/DAO) 👉 결과를 같은 JSP또는 다른 JSP로 출력
  • Controller역할을 JSP가 겸함 Model(JavaBean/DAO)은 별도 클래스

요청 흐름

Browser → list.jsp(컨트롤러 역할) → JavaBean/DAO → request.setAttribute(...)
       → (같은 JSP에서 렌더 or 다른 JSP로 forward)

짧은 예시

<%@ page import="com.example.MemberDao" %>
<jsp:useBean id="memberDao" class="com.example.MemberDao" />
<%
  var list = memberDao.findAll();          // 컨트롤러 역할
  request.setAttribute("members", list);   // 모델 전달
%>
<ul>
  <c:forEach var="m" items="${members}">
    <li>${m.name}</li>
  </c:forEach>
</ul>

Model 2 (MVC : Servlet Controller + JSP View)

어떻게 생겼나?

  • ServletFront Controller가 되어 라우팅, 검증, 권한, 예외, 로깅 등 흐름 제어를 한곳에서 처리
  • Service/DAO로 비즈니스 데이터 계층을 분리
  • JSPView전용(JSTL/EL)으로 표현만 담당
  • 필요한 데이터는 request.setAttribute()로 모델을 담아 forwardJSP에 전달

왜 이렇게 바뀌었나?

  • 관심사 분리를 강제해 테스트/리팩토링/협업을 가능하게 하려면 컨트롤러를 코드(서블릿)로 통일해야 했다.
  • 공통 로직(인증/로깅/인코딩)을 Filter/Interceptor에서 중앙집중으로 처리하고 싶었음
  • Post, Redirect, Get 국제화, 예외 처리 표준화 같은 베스트 프랙티스를 일관되게 적용하려면 중앙 진입점이 필요

개념

  • Servlet이 Controller, JSP는 View전용(JSTL/EL로만 표현)
  • Front Controller(하나의 서블릿)로 URL 매핑/검증/권한/예외/로그를 중앙집중
  • 오늘날 Spring MVC가 이 철학을 프레임워크로 표준화한 형태

💡 Model2는 규모와 팀을 견딜 수 있는 구조를 제공했고 오늘날 Spring MVC/Boot로 사실상 표준이 되었다.

요청 흐름

Browser → Servlet(Controller) → Service → DAO
       → request.setAttribute(... 모델 ...)
       → forward("/WEB-INF/views/xxx.jsp") → JSP(View)

짧은 예시

// controller
@WebServlet("/members/detail")
public class MemberController extends HttpServlet {
  private final MemberService svc = new MemberService();
  @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {
    String id = req.getParameter("id");
    if (id == null || id.isBlank()) { resp.sendError(400); return; }
    var member = svc.findById(id);
    if (member == null) { resp.sendError(404); return; }
    req.setAttribute("member", member);
    req.getRequestDispatcher("/WEB-INF/views/member/detail.jsp").forward(req, resp);
  }
}
// view
<!-- /WEB-INF/views/member/detail.jsp -->
<h1>회원 상세</h1>
<p>이름: ${member.name}</p>

비 MVC / Model 1 / Model 2 요약

📌 비-MVC (페이지 스크립틀릿 중심)

  • 핵심 아이디어 : JSP 한 장이 입력 처리 + 비즈니스 + 출력까지
  • 요청 흐름 : Browser → JSP(모두 처리) → HTML
  • 주 사용 기술 : JSP 스크립틀릿 <% ... %>, JDBC 직결
  • 장점 : 시작이 빠름, 파일 수 적음
  • 단점 : 뷰 로직 혼재, 테스트/확장/보안 취약, 유지보수 어려움

📌 Model 1

  • 핵심 아이디어 : JSP가 Controller+View, Model은 JavaBean
  • 요청 흐름 : Browser → JSP(컨트롤러 역할) → JavaBean/DAO → JSP(View)
  • 주 사용 기술 : JSP + JSTL + JavaBean
  • 장점 : Model 분리 일부 가능, 곡선 완만
  • 단점 : 여전히 컨트롤러가 JSP, URL/보안/검증의 중복

📌 Model 2

  • 핵심 아이디어 : Servlet Controller + JSP View (정통 MVC)
  • 요청 흐름 : Browser → Servlet(Controller) → Service/DAO → JSP(View)
  • 주 사용 기술 : Servlet, JSP/JSTL, Filter(Front Controller)
  • 장점 : 책임분리, 테스트/확장/보안 용이
  • 단점 : 초기 구조화 필요

0개의 댓글