-
Spring MVC 패턴 등장배경카테고리 없음 2025. 1. 28. 17:30
기존 Servlet, JSP방법으로 개발하면 하나의 클래스 내에 View코드와 비즈니스 로직 코드가 혼재하는 문제가 있음
[서블릿과 JSP의 한계]
서블릿으로 개발할 때는 뷰(View)화면을 위한 HTML을 만드는 작업이 자바 코드에 섞여서 지저분하고 복잡했다.
JSP를 사용한 덕분에 뷰를 생성하는 HTML 작업을 깔끔하게 가져가고, 중간중간 동적으로 변경이 필요한 부분에만 자
바 코드를 적용했다. 그런데 이렇게 해도 해결되지 않는 몇가지 고민이 남는다.
회원 저장 JSP를 보자. 코드의 상위 절반은 회원을 저장하기 위한 비즈니스 로직이고, 나머지 하위 절반만 결과를
HTML로 보여주기 위한 뷰 영역이다. 회원 목록의 경우에도 마찬가지다.
코드를 잘 보면, JAVA 코드, 데이터를 조회하는 리포지토리 등등 다양한 코드가 모두 JSP에 노출되어 있다. JSP가 너
무 많은 역할을 한다. 이렇게 작은 프로젝트도 벌써 머리가 아파오는데, 수백 수천줄이 넘어가는 JSP를 떠올려보면 정
말 지옥과 같을 것이다. (유지보수 지옥 썰)
*회원저장JSP
main/webapp/jsp/members.jsp` ```html <%@ page import="java.util.List" %> <%@ page import="hello.servlet.domain.member.MemberRepository" %> <%@ page import="hello.servlet.domain.member.Member" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <% MemberRepository memberRepository = MemberRepository.getInstance(); List<Member> members = memberRepository.findAll(); %> <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> <% for (Member member : members) { out.write(" <tr>"); out.write(" out.write(" out.write(" out.write(" </tr>"); <td>" + member.getId() + "</td>"); <td>" + member.getUsername() + "</td>"); <td>" + member.getAge() + "</td>"); } %> </tbody> </table> </body> </html>
==>
이러한 이슈로 MVC패턴이 등장
[ Servlet, jsp를 MVC로 변경 ]
- Servlet클래스 내에 Model, 비즈니스 로직 처리 (Repository.save함수 호출), View 렌더링이 분리되어 있음
* View (jsp) 코드
* redirect와 forward의 개념
리다이렉트는 실제 클라이언트(웹 브라우저)에 응답이 나갔다가, 클라이언트가 redirect 경로로 다시 요청한다.
따라서 클라이언트가 인지할 수 있고, URL 경로도 실제로 변경된다.
반면에 포워드는 서버 내부에서 일어나는 호출이기 때문에 클라이언트가 전혀 인지하지 못한다.
==> 하지만, MVC패턴에도 여전히 한계점 존재
- 컨트롤러는 중복이 많고 필요하지 않은 코드들이 존재
1) 포워드 중복
View로 이동하는 코드가 항상 중복 호출
물론 이 부분을 메서드로 공통화해도 되지만, 해당 메서드도 항상 직접 호출해야 한다.
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath); dispatcher.forward(request, response);
2) ViewPath에 중복
String viewPath = "/WEB-INF/views/new-form.jsp";
prefix: `/WEB-INF/views/`
suffix: `.jsp`
그리고 만약 jsp가 아닌 thymeleaf 같은 다른 뷰로 변경한다면 전체 코드를 다 변경해야 한다.
3) 공통 처리가 어렵다.
기능이 복잡해 질수록 컨트롤러에서 공통으로 처리해야 하는 부분이 점점 더 많이 증가할 것이다.
단순히 공통 기능을 메서드로 뽑으면 될 것 같지만, 결과적으로 해당 메서드를 항상 호출해야 하고, 실수로 호출하지 않으면 문제가 될 것이
다. 그리고 호출하는 것 자체도 중복이다.
**정리하면 공통 처리가 어렵다는 문제가 있다.**
이 문제를 해결하려면 컨트롤러 호출 전에 먼저 공통 기능을 처리해야 한다. 소위 **수문장 역할**을 하는 기능이 필요하다.
**프론트 컨트롤러(Front Controller) 패턴**을 도입하면 이런 문제를 깔끔하게 해결할 수 있다.(입구를 하나로!)
스프링 MVC의 핵심도 바로 이 프론트 컨트롤러에 있다.