
지난 포스트에서 Servlet에 대해서 알아보았다.
Servlet는 동적인 페이지를 응답할 수 있도록 해주는데 이를 응답을 반환을 해줄 때 view에 관한 로직이 보기가 별로 좋지 않은 즉, 가독성이 좋치 않은 문제가 있었다.
이를 해결하기 위해서 JSP라는 것이 나왔다.
이번 포스트에서 JSP와 JSP가 나오면서 등장을 하게 된 MVC패턴에 대해서 알아보자.
Servlet에서 view를 응답을 해줄 때, 가독성이 떨어지는 문제가 있었다.
@WebServlet(name = "responseHtmlServlet", urlPatterns = "/response-html")
public class ResponseHtmlServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<body>");
writer.println(" <div>안녕?</div>");
writer.println("</body>");
writer.println("</html>");
}
}
위에 코드를 보면 response객체를 이용해서 HTML을 만들어서 응답을 만들어주고 있다.
위에 HTML코드는 하나 하나 코드를 추가해 주어야 한다.
지금은 짧은 코드이기 때문에 가능하지만 내용이 많아지면 더 복잡해지고 더 가독성이 떨어질 것이다.
그래서 이러한 문제를 해결하기 위해서 나온 것이 템플릿 엔진이다.
템플릿 엔진은 동적인 HTML을 처리하기 위한 도구이다. 서버로부터 데이터를 받아서 HTML로 변환을 하는 역할을 담당을 하고 있다.
JSP도 이 템플릿엔진의 종류 중 하나이다.
템플릿 엔진이 JSP를 사용해서 username을 사용해보자.
(여기서는 JSP의 문법을 다루기보다는 JSP와 MVC패턴이 무엇인지 이해하는 데 중점을 둔다. 그래서 JSP의 문법은 다루지 않는다.)
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<html>
<head>
<title>제목</title>
</head>
<body>
<%
String username = "이상혁";
%>
<div>
Hello <%= username %>
</div>
</body>
</html>
JSP 문법을 사용을 해서 JSP내에서 변수를 선언과 초기화를 하고 HTML에서 사용하는 것을 볼 수 있다.
확실히 Servlet를 사용해서 HTML을 넘겨주는 것보다 덜 복잡하고 가독성이 좋다는 것을 느낄 수 있다.
그런데 한 가지 문제점이 생긴다.
JSP에서 view와 비지니스 로직 등 모든 부분이 들어가 있다가 보니 복잡해지고 복잡해지니 가독성이 떨어지고 결국에는 유지보수가 힘들어지게 되는 문제가 생겼다.
지금 위에 예시 코드에도 간단하지만 view를 나타내는 로직과 데이터를 관리하는 로직이 같이 있다.
지금은 간단하기 때문에 문제가 없지만 프로젝트가 커지게 되면 유지보수가 힘들어 질 것이다.
이러한 JSP를 해결하기 위해서 나온 것이 MVC패턴이다.
MVC 패턴은 Model, View, Controller의 앞 글자를 따서 표현을 한 것이다.
MVC 패턴은 애플리케이션을 3가지 역할로 구분해서 개발하는 개발론이다.
3가지 역할이 Model, View, Controller이다.
Model, View, Controller가 어떤 역할을 담당을 하는 지 알아보자.
Model : 데이터와 비지니스 로직을 처리하는 역할
View : UI, 보여지는 화면을 처리하는 역할
Controller : view와 model를 분리하고, view와 model을 연결하는 역할

이제 위에 도식표를 보면서 알아보자.
요청을 받는 것은 controller가 받는다. 그리고 이 요청을 model에제 전달을 하고 model은 비지니스 로직을 수행을 해고 다시 controller에게 전달을 한다.
그리고 controller는 데이터를 view에 전달을 하고 view는 데이터를 화면으로 유저에게 보여준다.
도식화와 글도 좋은 자료이지만 개발자는 코드를 쳐보면 공부를 하면 좀 더 이해가 빨라진다.
// model
@Getter
@NoArgsConstructor
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
Student라는 class로 model을 만들어 주었다.
model에서는 데이터를 저장하고 관리하는 역할을 한다.
package sample.servlet.study;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import sample.servlet.model.Student;
import java.io.IOException;
@WebServlet(name = "studentServlet", urlPatterns = "/student")
public class studentServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
int age = req.getIntHeader("age");
// 모델 샐성 및 데이터 전달
Student student = new Student(username, age);
// 뷰에 데이터 전달
req.setAttribute("student", student);
// view로 이동
req.getRequestDispatcher("/student.jsp").forward(req, resp);
}
}
이전에 배운 servlet를 이용해서 controller를 만들었다.
파라미터를 받아서 student model을 만들어 주었고 이를 view에 전달을 하고 view를 랜더링을 시겼다.
<jsp:useBean id="student" scope="request" type="javax.xml.stream.util.StreamReaderDelegate"/>
<%--
Created by IntelliJ IDEA.
User: isanghyeog
Date: 2024. 7. 30.
Time: PM 9:13
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Student Information</h1>
<p>Name: ${student.name}</p>
<p>Age: ${student.age}</p>
</body>
</html>
JSP를 통해서 동적인 페이지를 만들어서 controller에서 넘겨준 데이터를 보여주고 있다.
이렇게 Model, controller, view를 통해서 역할을 구분하기 때문에 가독성이 높아지고 내가 원하는 부분을 쉽게 건드릴 수 있다. 즉, 유지보수가 쉬워진다는 것이다.
하지만 이러한 mvc패턴도 한계점이 존재한다.
바로 한 요청마다 하나의 servlet이 매핑이 된다는 단점이다.
만약, 하나씩 매핑이 되서 실행이 되면 공통적인 로직이 중복이 되는 한계가 생긴다.
즉, 공통처리가 어렵다는 것이다.
다음 블로그에서는 이 문제를 해결하기 위해서 Spring MVC에서는 이 Servlet를 어떻게 사용을 하고 있는지 알아볼 것이다.
[10분 테코톡] 루키의 Servlet & Spring Web MVC
Java MVC 패턴 바로 알기
[10분 테코톡] 🧀 제리의 MVC 패턴
[10분 테코톡] 👩🏻💻👨🏻💻해리&션의 MVC 패턴