본문 바로가기
BE/Spring

Spring

by soohykim 2025. 4. 11.
728x90
반응형

📒 Servlet & Spring MVC

  • 발전 순서 : 순수 JAVA 웹 처리 구현 ➡️ Servlet ➡️ JSP ➡️ MVC1 ➡️ MVC2

📕 Web Server & WAS

  • Web Server : 정적 페이지 처리하는 서버
  • WAS : 동적 컨텐츠 생성해주는 서버

📕 Servlet

1) Servlet 개념

  • Java 기반의 웹 프로그래밍 기술 (.java 클래스로 자바의 모든 기능 가능)
  • Java 코드 안에 HTML 코드 넣음
  • 특징
    • 웹 서버 응답/요청을 직접 처리의 불편함 해소 ➡️ Data processing(Controller)에 좋음
    • 동적 HTML 생성의 불편함 해소
  • 장점
    • 스레드 기반의 빠른 처리 속도
  • 단점
    • Java코드를 컴파일한 후 동적 페이지 처리 ➡️ Servlet이 수정된 경우, 재컴파일 및 재배포 필요
    • 프로그램 내에서 HTML 작성하면, 화면 인터페이스 구현에 너무 많은 코드 필요함 ➡️ HTML 가독성 나쁨 (유지보수 문제)

2) Servlet 구현

  • Servlet 인터페이스 안에 service 메소드 존재
  • ServletRequest를 비즈니스 로직으로 처리해서 ServletResponse로 응답
  • Java 내장 라이브러리에 HTTPServlet이라는 추상 클래스 구현
  • HTTPServlet은 GenericServlet(서블릿 인터페이스)를 상속받음
  • 웹에서 오는 요청과 응답을 다루는 표준 프로토콜
  • doGet(), doPost() 등 메서드를 오버라이딩해서 원하는 로직 구현 가능 (오버라이딩)
  • 🗒️ 예시
package hello.servlet.web;

import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(name = "memberSaveServlet", urlPatterns = "/servlet/members/save")
public class MemberSaveServlet extends HttpServlet {

    private MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("MemberSaveServlet.service");

        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");

        String username = request.getParameter("username");
        int age = Integer.parseInt(request.getParameter("age"));

        Member member = new Member(username, age);
        memberRepository.save(member);

        PrintWriter w = response.getWriter();
        w.write("<html>\n" +
                "<head>\n" +
                " <meta charset=\"UTF-8\">\n" + "</head>\n" +
                "<body>\n" +
                "성공\n" +
                "<ul>\n" +
                "    <li>id="+member.getId()+"</li>\n" +
                "    <li>username="+member.getUsername()+"</li>\n" +
                " <li>age="+member.getAge()+"</li>\n" + "</ul>\n" +
                "<a href=\"/index.html\">메인</a>\n" + "</body>\n" +
                "</html>");
    }
}

3) Servlet 동작 과정

  • 사용자 요청이 들어옴 ➡ 웹 서버가 WAS에게 요청 위임 ➡ Servlet Container가 요청을 해결할 수 있는 Servlet을 찾아 응답

📕 JSP (Java Server Pages)

  • 서블릿 기반의 서버 스크립트 언어 (동적 웹페이지 생성)
  • HTML 코드 안에 Java 코드 넣음
  • 장점
    • HTML 작성이 편리하여 View 구현하기 좋음
    • JSP가 수정된 경우 ➡️ 재배포 필요 없이 WAS가 알아서 처리
    • 요청이 메모리에서 치리되어 빠른 처리속도
  • 🗒️ 예시
<%@ page import="hello.servlet.domain.member.Member" %>
<%@ page import="hello.servlet.domain.member.MemberRepository" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    MemberRepository memberRepository = MemberRepository.getInstance();
    System.out.println("MemberSaveServlet.service");

    String username = request.getParameter("username");
    int age = Integer.parseInt(request.getParameter("age"));

    Member member = new Member(username, age);
    memberRepository.save(member);
%>
<html>
<head>
    <title>Title</title>
</head>
<body>
성공
<ul>
    <li>id=<%=member.getId()%></li>
    <li>username=<%=member.getUsername()%></li>
    <li>age=<%=member.getAge()%></li>
</ul>
<a href="/index.html">메인</a>
</body>
</html>

📕 MVC (Model-View-Container) 패턴

1) MVC 개념

  • Servlet + JSP 형태
  • Model
    • View에 출력할 데이터 담음
    • 뷰에서 모델만 보고 꺼내서 써서, 렌더링에 집중함
  • View : 사용자의 요청을 화면으로 출력 (JSP)
  • Controller : 사용자 요청을 처리, 요청에 따른 전체적인 흐름 제어 (Servlet)
  • FrontController 패턴을 접목한 웹 어플리케이션 프레임워크
  • 서블릿이 호출되면 HttpServlet이 제공하는 service() 호출
    ➡️ 스프링 MVC DispatcherServlet의 부모인 FrameworkServlet에서 service() 오버라이드
    ➡️ FrameworkServlet.service()를 시작하고, 여러 메서드가 호출되면서 DispatcherServlet.doDispatcher() 호출됨

사용자가 정보를 Controller에게 요청 ➡️ 비즈니스 로직 수행 중 필요시 Model호출하여 데이터 요청 ➡️ 완료시 View를 통해 화면에 출력

2) MVC 요소

  • Handler Mapping
    • 요청을 처리할 Handler 찾는 역할 (Controller)
    • 요청된 URL에 매핑되는 핸들러(컨트롤러)를 찾아서 반환하는 메서드
  • Handler Adaptor
    • Handler의 실제 로직을 수행하는 역할
    • 핸들러의 종류에 관계없이 해당 핸들러 실행할 수 있도록 함
    • support ➡️ true이면, handle 메서드로 핸들러 로직 수행
  • View Resolver
    • 반환된 View 이름을 실제 View 객체로 변환하는 역할
    • ModelAndView : 컨트롤러에서 처리한 데이터(모델)과 해당 데이터를 표시할 View의 정보를 가진 객체

  • Dispatcher Servlet
    • Handler 매핑
    • 인터페이스로 구현된 HandlerMapping, HandlerAdapter, ViewResolver를 리스트로 가짐

📖 참고 📖 doDispatch 동작 순서

  • 처음 FrontController 역할
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        ModelAndView mv = null;
        // 1. 핸들러 조회
        mappedHandler = getHandler(processedRequest);
        if (mappedHandler == null) {
            noHandleFound(processedRequest, response);
            return;
        }
        // 2.핸들러 어댑터 조회-핸들러를 처리할 수 있는 어댑터
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        // 3. 핸들러 어댑터 실행 -> 4. 핸들러 어댑터를 통해 핸들러 실행 -> 5. ModelAndView 반환
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
        processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    }
    private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, 
                                       HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {
        // 뷰 렌더링 호출
        render(mv, request, response);
    }
    protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
        View view;
        String viewName = mv.getViewName();
        // 6. 뷰 리졸버를 통해서 뷰 찾기, 7.View 반환
        view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
        // 8. 뷰 렌더링
        view.render(mv.getModelInternal(), request, response);
    }

3) MVC 종류

  • MVC1
    • JSP가 뷰 + 컨트롤러 역할
    • JSP에 Java코드와 Html, css 코드 섞여 있어 소스 복잡
    • 장점 : 설계 간단, 개발 속도 빠름 (작은 프로젝트에 적합)
    • 단점 : 읽기가 어렵고, 유지보수 힘듦
  • MVC2
    • JSP가 뷰, Servlet이 컨트롤러 역할
    • Servlet이 요청 받고, 비즈니스 로직 수행하며 모델 호출 ➡️ 뷰 역할인 JSP 제어하여 화면 출력
    • JSP는 Java코드 안쓰고, JSTL 사용하여 결과를 화면에 출력
    • 장점 : 확장에 용이, 유지보수 수월함
    • 단점 : 초기 설계단계에 비용 많이 듦

📖 참고 📖 JSTL

  • 자바 서버 페이지 표준 태그 라이브러리 (Javaserver pages Standard Tag Library)
  • Java EE 기반의 웹 애플리케이션 개발 플랫폼을 위한 컴포넌트 모음
  • XML 데이터 처리, JSP 태그 라이브러리 추가하여 JSP 사양 확장
  • 🗒️ 예시 (Controller)
package hello.servlet.web.servletmvc;

import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@WebServlet(name = "mvcMemberListServlet", urlPatterns = "/servlet-mvc/members")
public class MvcMemberListServlet extends HttpServlet {

    private MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List<Member> members = memberRepository.findAll();
        request.setAttribute("members", members);

        String viewPaht = "/WEB-INF/views/members.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPaht);
        dispatcher.forward(request, response);
    }
}
  • 🗒️ 예시 (View)
// /WEB-INF/views/members.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<a href="/index.html">메인</a>
<table>
  <thead>
  <th>id</th>
  <th>username</th>
  <th>age</th>
  </thead>
  <tbody>
  <c:forEach var="item" items="${members}">
    <tr>
      <td>${item.id}</td>
      <td>${item.username}</td>
      <td>${item.age}</td>
    </tr>
  </c:forEach>
  </tbody>
</table>
</body>
</html>

728x90
반응형

'BE > Spring' 카테고리의 다른 글

스프링 부트, 웹 MVX, DB접근 기술  (0) 2025.04.10
HTTP  (0) 2025.04.10
Servlet/JSP/JDBC  (1) 2025.04.10
Spring Framework  (0) 2025.04.10
Spring Boot  (0) 2025.04.10