내배캠 TIL 24일차

오병택·2025년 3월 21일

내배캠

목록 보기
46/73

학습 요약

Spring 입문 강의

Spring 입문 3주차

MVC 패턴 1강

Template Engine

동적인 웹 페이지를 생성하기 위해 사용되는 도구이며 템플릿을 기반으로 정적인 부분과 동적인 데이터를 결합하여 HTML, XML 등의 문서를 생성하는 역할을 수행

템플릿 엔진이 나온 이유

자바 코드로 HTML을 만들어 내는 것이 아닌 HTML 문서에 동적으로 변경해야 하는 부분만 자바 코드를 넣을 수 있다면 더 편리하기 때문

대표적인 템플릿 엔진

  1. Thymeleaf
    • Spring과 통합👍
    • 다양한 기능을 포함
  2. JSP(Java Server Pages)
  3. FreeMarker
  4. Velocity
  5. Mustache

MVC 패턴 개요

Servlet이나 JSP만으로 비지니스 로직과 View Rendering 까지 모두 처리하면 너무 많은 역할을 하게 되고 유지보수가 굉장히 어려워져서(책임이 너무 많음) 고안된 패턴

1. Servlet 예시

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

Servlet 문제점

  • 화면을 그리는 View 영역과 비지니스 로직이 Servlet 하나에 모두 섞여있음
  • 책임을 너무 많이 가지고 있음

2. 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>

Servlet 코드에서 HTML을 만드는 부분인 View가 분리

Servlet과 JSP 구조


Servlet, JSP 방식의 문제점
1. Servlet만을 사용한 경우 View를 위한 코드와 비지니스 로직을 처리하는 코드가 Servlet에 모두 존재하여 유지보수가 어려워짐
2. JSP를 사용하여 View를 분리하였지만 비지니스 로직의 일부가 JSP 파일안에 존재한다. 여전히 책임이 많아 유지보수가 어려움

MVC 패턴

하나의 Servlet이나 JSP로 처리하던 것들을 Model, View, Controller 영역으로 나눈 것

핵심 내용

  • View가 분리된 이유의 핵심은 변경
  • 기획이 변하지 않는 이상 비지니스 로직과 View의 수정 원인은 별개로 발생
    • 화면 구성에 수정이 발생하면 View만 변경
    • 요구사항에 수정이 발생하는 경우 비지니스 로직 변경
  • 즉, 서로 연관이 없는 코드끼리 함께 존재할 필요X. 완전히 분리

MVC 패턴 구조

Controller

  • 예시 코드에서 Servlet에 해당하는 영역
  1. HTTP Request를 전달받아 파라미터를 검증
  2. 비지니스 로직을 실행
    • 비지니스 로직을 Controller에 포함하게되면 Controller가 너무 많은 역할을 담당하게 되어 일반적으로 Service Layer를 별도로 만들어서 처리
    • Database와 상호작용 하는 Layer를 따로 구분하여 Repository Layer를 추가로 구성
    • 위와 관련된 자세한 내용인 Layered Architecture는 6주차에서 나오니까 그때 쓰도록 하겠습니다. (~ ̄▽ ̄)~
    • Controller도 비지니스 로직을 포함할 수 있지만 일반적으로 Service Layer를 호출하는 역할을 담당
  3. View에 전달할 결과를 조회하여 Model 객체에 임시로 저장

Model

  1. View에 출력할 Data를 저장하는 객체
  2. View는 비지니스 로직이나 Data 접근을 몰라도 되고 View Rendering에만 집중(책임 분리)

View

  • 예시 코드에서 JSP에 해당하는 영역
  1. Model 객체에 담겨져 있는 Data를 사용하여 화면을 Rendering함

MVC 패턴 2강

MVC 패턴의 문제점

MVC 패턴을 적용 후 View의 역할은 필요한 데이터를 Model 에서 참조하여 화면을 그리는 역할만 수행하면 된다. 하지만 Controller에 해당하는 부분은 여전히 문제를 가지고 있음

MVC 패턴 적용

문제점

  1. dispatcher.forward(request, response) View로 이동하는 forward가 항상 중복 호출
  2. String path= “/WEB-INF/views/new-form.jsp” View의 path를 입력(중복 작업)
    1. jsp 파일의 경로 혹은 이름이 바뀌면 해당 코드가 변경되어야 함
    2. JSP 이외의 확장자를 사용하려면 전체가 변경되어야 함
  3. HttpServletResponse 객체를 사용하는 경우가 적음 (JSP에서 모두 해결하기 때문)
    1. HttpServletRequest와 HttpServletResponse는 Test 코드를 작성하기도 매우 힘듬
  4. 공통 기능이 추가될수록 Controller에서 처리해야 하는 부분들이 많아짐

공통 기능 처리

모든 컨트롤러에서 공통으로 적용되는 기능
ex) Log 출력, 인증, 인가 등

프론트 컨트롤러 패턴

Servlet(Controller)이 호출되기 전에 공통 기능을 하나의 Servlet에서 처리해주는 패턴

  • 프론트 컨트롤러(Servlet) 하나에 모든 클라이언트측 요청이 들어옴

프론트 컨트롤러 패턴 구조

프론트 컨트롤러의 역할

  1. 모든 요청을 하나의 프론트 컨트롤러가 받음
  2. 공통 기능을 처리
  3. 요청을 처리할 수 있는 Controller를 찾아서 호출(Controller Mapping)
  4. 프론트 컨트롤러를 제외한 나머지 컨트롤러는 Servlet을 사용하지 않아도 됨
    • 일반 Controller들은 HttpServlet을 상속받거나, @WebServlet을 사용하지 않아도 됨

어댑터 패턴

다양한 컨트롤러(Handler)를 유연하게 만들어 서로 다른 인터페이스를 갖는 두 클래스를 연결해주는 패턴

어댑터 패턴 구조


1. 컨트롤러(Handler)는 비지니스 로직을 처리하고 알맞은 결과를 반환
2. 어댑터는 공통 로직과 컨트롤러(Handler)가 자연스럽게 연결되도록 함
3. 프론트 컨트롤러는 공통으로 처리되는 로직을 수행

어댑터 패턴 장점

  • 프론트 컨트롤러, 어댑터, 핸들러 모두 각자의 역할만 수행 (책임 분리)
  • 새로운 컨트롤러(Handler)가 추가되어도 컨트롤러와 어댑터만 추가한다면 공통 로직의 변경이 발생X

느낀 점

6주차까지 강의를 거의 다 들었는데 3주차가 제일 어려운 것 같다. 뭔가 최종보스가 중간에 껴있는 느낌인데 주말에 이 부분을 확실히 이해하면 도움이 많이 될 것 같다. 3주차 부분은 주말에 이어서 적어보도록 할게여 오늘 강의 많이 들어서 어지럽네요ㅎㅎ 😁

profile
걱정하지 말고 일단 해봐!

0개의 댓글