๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
IT/Spring

[์ธํ”„๋Ÿฐ - ์Šคํ”„๋ง MVC 1ํŽธ] MVC๋กœ ํšŒ์› ๊ด€๋ฆฌ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งŒ๋“ค๊ธฐ

by YeonBu 2024. 5. 25.
728x90

 

 

/* ์ด ๊ธ€์€ ๊น€์˜ํ•œ๋‹˜์˜ ๊ฐ•์˜๋ฅผ ๋ณด๊ณ  ์ •๋ฆฌํ•˜๋ ค๊ณ  ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

   ๊ฐœ์ธ์ ์ธ ๊ณต๋ถ€๋ฅผ ์œ„ํ•ด ์˜ฌ๋ฆฌ๋Š” ๊ธ€์ด๋ฏ€๋กœ ์ค‘๊ฐ„ ์ค‘๊ฐ„ ์ฝ”๋“œ๋Š” ์ƒ๋žต๋˜์—ˆ์Šต๋‹ˆ๋‹ค. */

 

 

 

์Šคํ”„๋ง MVC 1ํŽธ - ๋ฐฑ์—”๋“œ ์›น ๊ฐœ๋ฐœ ํ•ต์‹ฌ ๊ธฐ์ˆ  | ๊น€์˜ํ•œ - ์ธํ”„๋Ÿฐ

๊น€์˜ํ•œ | ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•  ๋•Œ ํ•„์š”ํ•œ ๋ชจ๋“  ์›น ๊ธฐ์ˆ ์„ ๊ธฐ์ดˆ๋ถ€ํ„ฐ ์ดํ•ดํ•˜๊ณ , ์™„์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํ”„๋ง MVC์˜ ํ•ต์‹ฌ ์›๋ฆฌ์™€ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๊ณ , ๋” ๊นŠ์ด์žˆ๋Š” ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๋กœ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ์Šต

www.inflearn.com

 

 

 

1. MVCํŒจํ„ด ๊ฐœ์š”

 

1) ๋„ˆ๋ฌด ๋งŽ์€ ์—ญํ• 

- ํ•˜๋‚˜์˜ ์„œ๋ธ”๋ฆฟ์ด๋‚˜ JSP๋งŒ์œผ๋กœ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ๋ทฐ ๋ Œ๋”๋ง๊นŒ์ง€ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋˜๋ฉด, ๋„ˆ๋ฌด ๋งŽ์€ ์—ญํ• ์„ ํ•˜๊ฒŒ ๋˜๊ณ 

  ๊ฒฐ๊ณผ์ ์œผ๋กœ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ์ง„๋‹ค.

  (HTML ์ฝ”๋“œ ํ•˜๋‚˜ ์ˆ˜์ •ํ•ด์•ผํ•˜๋Š”๋ฐ ์ˆ˜๋ฐฑ์ค„์˜ ์ž๋ฐ” ์ฝ”๋“œ๊ฐ€ ์žˆ๊ฑฐ๋‚˜, ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ํ•˜๋‚˜๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ๋˜๋Š”๋ฐ 

   ์ˆ˜๋ฐฑ, ์ˆ˜์ฒœ์ค„์˜ HTML์ฝ”๋“œ๊ฐ€ ํ•จ๊ป˜ ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด๋ณด๋ฉด ๋œ๋‹ค)

 

2) ๋ณ€๊ฒฝ์˜ ๋ผ์ดํ”„ ์‚ฌ์ดํด

- ์ง„์งœ ๋ฌธ์ œ๋Š” ๋‘˜ ์‚ฌ์ด์˜ ๋ผ์ดํ”„ ์‚ฌ์ดํด์ด ๋‹ค๋ฅด๋‹ค๋Š” ์ ์ด๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด UI ์ผ๋ถ€๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ์ผ๊ณผ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„

  ์ˆ˜์ •ํ•˜๋Š” ์ผ์€ ๊ฐ๊ฐ ๋‹ค๋ฅด๊ฒŒ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋งค์šฐ ๋†’๊ณ , ๋Œ€๋ถ€๋ถ„ ์„œ๋กœ์—๊ฒŒ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.

  ์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝ์˜ ๋ผ์ดํ”„ ์‚ฌ์ดํด์ด ๋‹ค๋ฅธ ๋ถ€๋ถ„์„ ํ•˜๋‚˜์˜ ์ฝ”๋“œ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์ข‹์ง€ ์•Š๋‹ค.

 

3) ๊ธฐ๋Šฅ ํŠนํ™”

- ํŠนํžˆ JSP ๊ฐ™์€ ๋ทฐ ํ…œํ”Œ๋ฆฟ์€ ํ™”๋ฉด์„ ๋ Œ๋”๋ง ํ•˜๋Š”๋ฐ ์ตœ์ ํ™” ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ถ€๋ถ„์˜ ์—…๋ฌด๋งŒ ๋‹ด๋‹นํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ

  ํšจ๊ณผ์ ์ด๋‹ค.

 

4) Model View Controller

- MVC ํŒจํ„ด์€ ์ง€๊ธˆ๊นŒ์ง€ ํ•™์Šตํ•œ ๊ฒƒ ์ฒ˜๋Ÿผ ํ•˜๋‚˜์˜ ์„œ๋ธ”๋ฆฟ, JSP๋กœ ์ฒ˜๋ฆฌํ•˜๋˜ ๊ฒƒ์„ ์ปจํŠธ๋กค๋Ÿฌ์™€ ๋ทฐ๋ผ๋Š” ์˜์—ญ์œผ๋กœ ์„œ๋กœ ์—ญํ• ์„

  ๋‚˜๋ˆˆ ๊ฒƒ์„ ๋งํ•œ๋‹ค. ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋ณดํ†ต MVC ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ๋‹ค

- Controller : HTTP ์š”์ฒญ์„ ๋ฐ›์•„ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฒ€์ฆํ•˜๊ณ , ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์‹คํ–‰ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ทฐ์— ์ „๋‹ฌํ•  ๊ฒฐ๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ

  ์กฐํšŒํ•ด์„œ ๋ชจ๋ธ์— ๋‹ด๋Š”๋‹ค

- Model : ๋ทฐ์— ์ถœ๋ ฅํ•  ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์•„๋‘”๋‹ค. ๋ทฐ๊ฐ€ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ๋ชจ๋ธ์— ๋‹ด์•„์„œ ์ „๋‹ฌํ•ด์ฃผ๋Š” ๋•๋ถ„์— ๋ทฐ๋Š” ๋น„์ฆˆ๋‹ˆ์Šค

  ๋กœ์ง์ด๋‚˜ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ์„ ๋ชฐ๋ผ๋„ ๋˜๋ฉฐ, ํ™”๋ฉด์„ ๋ Œ๋”๋ง ํ•˜๋Š” ์ผ์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

- View : ๋ชจ๋ธ์— ๋‹ด๊ฒจ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๋Š” ์ผ์— ์ง‘์ค‘ํ•œ๋‹ค. = HTML

 

* ์ปจํŠธ๋กค๋Ÿฌ์— ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋‘˜ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด ๋„ˆ๋ฌด ๋งŽ์€ ์—ญํ• ์„ ๋‹ด๋‹นํ•˜๋ฏ€๋กœ '์„œ๋น„์Šค(Service)' ๋ผ๋Š” ๊ณ„์ธต์„

  ๋ณ„๋„๋กœ ๋งŒ๋“ค์–ด์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ปจํŠธ๋กค๋Ÿฌ๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์žˆ๋Š” ์„œ๋น„์Šค๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์—ญํ• ์„ ๋‹ด๋‹นํ•œ๋‹ค.

 

 

 

 

2. MVCํŒจํ„ด ์ ์šฉ

 

- ์„œ๋ธ”๋ฆฟ์„ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์‚ฌ์šฉํ•˜๊ณ , JSP๋ฅผ ๋ทฐ๋กœ ์‚ฌ์šฉํ•ด์„œ MVCํŒจํ„ด์„ ์ ์šฉํ•ด๋ณด์ž

 

1) ํšŒ์› ๋“ฑ๋ก ํผ

 

ํšŒ์› ๋“ฑ๋ก ํผ - ์ปจํŠธ๋กค๋Ÿฌ

@WebServlet(name = "mvcMemberFormServlet", urlPatterns = "/servlet-mvc/members/new-form")
public class MvcMemberFormServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String viewPath = "/WEB-INF/views/new-form.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);
        
    }
}

 

- dispatcher.forward() : ๋‹ค๋ฅธ ์„œ๋ธ”๋ฆฟ์ด๋‚˜ JSP๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ. ์„œ๋ฒ„ ๋‚ด๋ถ€์—์„œ ๋‹ค์‹œ ํ˜ธ์ถœ์ด ๋ฐœ์ƒ

- /WEB-INF : ์ด ๊ฒฝ๋กœ์•ˆ์— JSP๊ฐ€ ์žˆ์œผ๋ฉด ์™ธ๋ถ€์—์„œ ์ง์ ‘ JSP๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋‹ค.

- redirct / forward : ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๋Š” ์‹ค์ œ ํด๋ผ์ด์–ธํŠธ(์›น ๋ธŒ๋ผ์šฐ์ €)์— ์‘๋‹ต์ด ๊ฐ”๋‹ค๊ฐ€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ redirect ๊ฒฝ๋กœ๋กœ ๋‹ค์‹œ

  ์š”์ฒญํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ๊ณ  URL๋„ ๋ณ€๊ฒฝ๋œ๋‹ค. ๋ฐ˜๋ฉด์— forward๋Š” ์„œ๋ฒ„ ๋‚ด๋ถ€์—์„œ ์ผ์–ด๋‚˜๋Š” ํ˜ธ์ถœ์ด๊ธฐ

  ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ „ํ˜€ ์ธ์ง€ํ•˜์ง€ ๋ชปํ•œ๋‹ค.

 

 

ํšŒ์› ๋“ฑ๋ก ํผ - ๋ทฐ

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
     <meta charset="UTF-8">
     <title>Title</title>
    </head>
    <body>
        <!-- ์ƒ๋Œ€๊ฒฝ๋กœ ์‚ฌ์šฉ, [ํ˜„์žฌ URL์ด ์†ํ•œ ๊ณ„์ธต ๊ฒฝ๋กœ + /save] -->
        <form action="save" method="post">
             username: <input type="text" name="username" />
             age: <input type="text" name="age" />
             <button type="submit">์ „์†ก</button>
        </form>
    </body>
</html>

 

- ์—ฌ๊ธฐ์„œ form์˜ action์„ ๋ณด๋ฉด ๊ฒฝ๋กœ๊ฐ€ '/' ๋กœ ์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ์ƒ๋Œ€๊ฒฝ๋กœ์ธ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ƒ๋Œ€๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด,

   ํผ ์ „์†ก์‹œ ํ˜„์žฌ URL์ด ์†ํ•œ ๊ณ„์ธต ๊ฒฝ๋กœ + save๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค

  * ํ˜„์žฌ ๊ณ„์ธต ๊ฒฝ๋กœ : /servlet-mvc/members/

  * ๊ฒฐ๊ณผ : /servelt-mvc/members/save

 

 

2) ํšŒ์› ์ €์žฅ

 

ํšŒ์› ์ €์žฅ - ์ปจํŠธ๋กค๋Ÿฌ

@WebServlet(name = "mvcMemberSaveServlet", urlPatterns = "/servlet-mvc/members/save")
public class MvcMemberSaveServlet extends HttpServlet {

    private MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

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

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

        // Model์— ๋ฐ์ดํ„ฐ ๋ณด๊ด€
        request.setAttribute("member", member);

        String viewPath = "/WEB-INF/views/save-result.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);

    }

}

 

- request๊ฐ€ ์ œ๊ณตํ•˜๋Š” setAttribute()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด request ๊ฐ์ฒด์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๊ด€ํ•ด์„œ ๋ทฐ์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

ํšŒ์› ์ €์žฅ - ๋ทฐ

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        ์„ฑ๊ณต
        <ul>
            <li>id=${member.id}</li>
            <li>username=${member.username}</li>
            <li>age=${member.age}</li>
        </ul>
        <a href="/index.html">๋ฉ”์ธ</a>
    </body>
</html>

 

- <%= request.getAttribute("member") %>๋กœ ๋ชจ๋ธ์— ์ €์žฅํ•œ member ๊ฐ์ฒด๋ฅผ ๊บผ๋‚ผ ์ˆ˜ ์žˆ์ง€๋งŒ ๋ณต์žกํ•˜๋‹ค.

  JSP๋Š” ${ } ๋ฌธ๋ฒ•์„ ํ†ตํ•˜์—ฌ attribute์— ๋‹ด๊ธด ๋ฐ์ดํ„ฐ๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

3) ํšŒ์› ๋ชฉ๋ก ์กฐํšŒ

 

ํšŒ์› ๋ชฉ๋ก ์กฐํšŒ - ์ปจํŠธ๋กค๋Ÿฌ

@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 viewPath = "/WEB-INF/views/members.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);

    }
}

 

 

 

ํšŒ์› ๋ชฉ๋ก ์กฐํšŒ - ๋ทฐ

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<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>
                <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>

 

 

 

3. MVCํŒจํ„ด ํ•œ๊ณ„

 

- MVC ํŒจํ„ด์„ ์ ์šฉํ•œ ๋•๋ถ„์— ์ปจํŠธ๋กค๋Ÿฌ์˜ ์—ญํ• ๊ณผ ๋ทฐ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ์—ญํ• ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

  ๊ทธ๋Ÿฐ๋ฐ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ๋”ฑ ๋ด๋„ ์ค‘๋ณต์ด ๋งŽ๊ณ , ํ•„์š”ํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋“ค๋„ ๋งŽ์ด ๋ณด์ธ๋‹ค

 

MVC ์ปจํŠธ๋กค๋Ÿฌ์˜ ๋‹จ์ 

 

1) ํฌ์›Œ๋“œ ์ค‘๋ณต

 : view๋กœ ์ด๋™ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ํ•ญ์ƒ ์ค‘๋ณต ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•œ๋‹ค. ๋ฌผ๋ก  ์ด ๋ถ€๋ถ„์„ ๋ฉ”์†Œ๋“œ๋กœ ๊ณตํ†ตํ™” ํ•ด๋„ ๋˜์ง€๋งŒ,

   ๋ฉ”์„œ๋“œ๋„ ํ•ญ์ƒ ์ง์ ‘ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);

 

2) ViewPath ์ค‘๋ณต

String viewPath = "/WEB-INF/views/members.jsp";

 

3) ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ

HttpServletRequest request, HttpServletResponse response

 

4) ๊ณตํ†ต์ฒ˜๋ฆฌ๊ฐ€ ์–ด๋ ต๋‹ค

 : ๊ธฐ๋Šฅ์ด ๋ณต์žกํ•ด์งˆ์ˆ˜๋ก ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๊ณตํ†ต์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์ด ์ ์  ๋” ๋งŽ์ด ์ฆ๊ฐ€ํ•  ๊ฒƒ์ด๋‹ค. ๋‹จ์ˆœํžˆ ๊ณตํ†ต ๊ธฐ๋Šฅ์„

   ๋ฉ”์„œ๋“œ๋กœ ๋ฝ‘์œผ๋ฉด ๋  ๊ฒƒ ๊ฐ™์ง€๋งŒ ๊ฒฐ๊ณผ์ ์œผ๋กœ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ํ•ญ์ƒ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

 

* ์ •๋ฆฌํ•˜์ž๋ฉด ๊ณตํ†ต ์ฒ˜๋ฆฌ๊ฐ€ ์–ด๋ ต๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.

  ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ์ปจํŠธ๋กค๋Ÿฌ ํ˜ธ์ถœ ์ „์— ๋จผ์ € ๊ณตํ†ต ๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค. Front Controller ํŒจํ„ด์„ ๋„์ž…ํ•˜๋ฉด

  ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค(์ž…๊ตฌ๋ฅผ ํ•˜๋‚˜๋กœ). ์Šคํ”„๋ง MVC์˜ ํ•ต์‹ฌ๋„ ๋ฐ”๋กœ ์ด ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ์— ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค!

 

 

๋ฐ˜์‘ํ˜•