STUDY - Spring

์ˆ˜ํ˜„ยท2023๋…„ 8์›” 8์ผ
0

IT (CS)

๋ชฉ๋ก ๋ณด๊ธฐ
8/12

๐Ÿ“’ 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>

profile
Notion์œผ๋กœ ์ด๋™ (https://24tngus.notion.site/3a6883f0f47041fe8045ef330a147da3?v=973a0b5ec78a4462bac8010e3b4cd5c0&pvs=4)

0๊ฐœ์˜ ๋Œ“๊ธ€