[Spring] MVC 패턴 (1)

이연우·2025년 7월 22일

TIL

목록 보기
20/100

🧪 Template Engine(템플릿 엔진)이란?

  • 정적인 HTML에 동적 데이터를 결합해 웹 페이지를 생성하는 도구
    → SSR(Server Side Rendering)에 사용됨

📌 등장 이유

  • Java 코드로 HTML을 출력하는 건 너무 불편함
  • HTML에 필요한 부분만 Java 코드를 삽입하는 방식이 더 효율적

🔹 대표 템플릿 엔진

  • Thymeleaf (스프링과 통합 우수)
  • JSP (과거에 주로 사용)
  • FreeMarker, Velocity, Mustache 등

🔄 MVC 패턴 개요

  • 하나의 Servlet/JSP에 모든 역할을 몰아주는 방식의 한계를 극복하기 위한 아키텍처
    Model-View-Controller로 분리하여 유지 보수를 용이하게 함

1. Servlet 방식

  • 비즈니스 로직 + 화면 구성 코드 → 모두 doGet() 또는 doPost()에 혼합됨
@WebServlet("/hello-world")
public class HelloWorldServlet extends HttpServlet {
		
		// User 저장소
    private UserRepository repository = new UserRepository();
    
    public HelloWorldServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        
        try {
            // 비지니스 로직을 처리하는 코드
            // 파라미터 조회 
            String userIdParam = request.getParameter("userId");
            Long userId = null;
            if (userIdParam != null) {
                userId = Long.parseLong(userIdParam);
            }
            
            // 회원 조회 
            String userInfo = repository.findById(userId);
            
            // 화면을 그리는 코드 START
            out.println("<h1>Hello World!</h1>");
            out.println("<div>조회한 회원의 정보: " + userInfo + "</div>");
            // 화면을 그리는 코드 END
            
           
        } catch (NumberFormatException e) {
	        // parsing 에러가 발생한 경우
            out.println("<div>Invalid user ID format</div>");
        } finally {
            out.close();
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {        
        doGet(request, response);
    }
}

📉 문제점:

  • 비즈니스 로직, 예외 처리, 화면 출력이 뒤섞여 가독성 및 유지 보수 매우 어려움

2. JSP 방식

  • 비즈니스 로직 일부가 JSP 내부에 존재 (예: 데이터 조회, 저장 로직)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
		<!-- HTML 코드... -->
		<!-- <%...%> 영역에는 Java 코드를 사용할 수 있다. -->
    <%
		    // 게시글 저장소 싱글톤으로 인스턴스 생성
		    BoardRepository boardRepository = BoardRepository.getInstance();
		    
		    // 게시글 제목, 내용 
        String title = request.getParameter("title");
        String content = request.getParameter("content");
        
        // 게시글 객체 생성
        Board board = new Baord(title, content);
        
        // 게시글 객체 저장
        repository.save(board);
        
    %>
    <div>
        ID : <input type ="text" name = "id" value="<%=id %>">
    </div>
		<!-- JSP 코드... -->
		<!-- HTML 코드... -->
    <jsp:forward page="<%=url %>" />
</body>
</html>

📉 문제점:

  • View 분리는 했지만 여전히 비즈니스 로직과 뒤섞임
  • JSP도 너무 많은 책임을 가짐

> Servlet과 JSP 구조

❗ Servlet & JSP 한계

항목문제점
Servlet비즈니스 로직과 View 코드 혼합 → 유지보수 어려움
JSPView로 분리했지만 여전히 로직 존재 → 책임 과다

🧩 MVC 패턴 구조

  • 관심사 분리(Separation of Concerns)를 통해 각 계층의 역할을 명확히 분리

🔸 Controller

  • HTTP 요청 수신
  • 파라미터 검증, 서비스 호출
  • 결과를 Model에 담아 View로 전달
    → (보통은 Service Layer를 통해 로직 실행)

🔹 Model

  • View에서 사용할 데이터를 저장
    → 비즈니스 로직과는 무관

🔸 View

  • Model 데이터를 사용해 HTML 화면을 렌더링
    → 데이터 처리나 로직은 몰라도 됨

🧱 전체 구조 시각화:

Client → Controller → Service → Repository → DB
                    ↓
                Model (Data)
                    ↓
                View (HTML)

0개의 댓글