[Spring] 3.์„œ๋ธ”๋ฆฟ, JSP, MVC ํŒจํ„ด

 

1. ํšŒ์› ๊ด€๋ฆฌ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์š”๊ตฌ์‚ฌํ•ญ

[ํšŒ์› ์ •๋ณด]

์ด๋ฆ„ : username

๋‚˜์ด : age

 

[๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ]

ํšŒ์›์ €์žฅ

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

 

[ํšŒ์› ๋„๋ฉ”์ธ ๋ชจ๋ธ]

@Getter @Setter
public class Member {
  private Long id;
  private String username;
  private int age;
  
  public Member() {
  }
  
  public Member(String username, int age) {
    this.username = username;
    this.age = age;
  }
}

* id๋Š” ํšŒ์› repo(์ €์žฅ์†Œ)์— ์ €์žฅํ•˜๋ฉด repo๊ฐ€ ํ• ๋‹น

 

ํšŒ์› ์ €์žฅ์†Œ

/**
* ๋™์‹œ์„ฑ ๋ฌธ์ œ๊ฐ€ ๊ณ ๋ ค๋˜์–ด ์žˆ์ง€ ์•Š์Œ, 
* ์‹ค๋ฌด์—์„œ๋Š” ConcurrentHashMap, AtomicLong ์‚ฌ์šฉ ๊ณ ๋ ค
*/
public class MemberRepository {
  private static Map<Long, Member> store = new HashMap<>(); //static ์‚ฌ์šฉ
  private static long sequence = 0L; //static ์‚ฌ์šฉ

  private static final MemberRepository instance = new MemberRepository();
  
  public static MemberRepository getInstance() {
    return instance;
  }
  
  private MemberRepository() {
  }

  public Member save(Member member) {
    member.setId(++sequence);
    store.put(member.getId(), member);
    return member;
  }
  
  public Member findById(Long id) {
    return store.get(id);
  }
  
  public List<Member> findAll() {
    return new ArrayList<>(store.values());
  }
  
  public void clearStore() {
    store.clear();
  } 
}

* ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์— static ์—†์–ด๋„ ๋จ

ํšŒ์› ์ €์žฅ์†Œ๋Š” ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ์ ์šฉํ–ˆ๋‹ค.
์Šคํ”„๋ง์„ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๋ฉด ๋˜์ง€๋งŒ, ์ง€๊ธˆ์€ ์ตœ๋Œ€ํ•œ ์Šคํ”„๋ง ์—†์ด ์ˆœ์ˆ˜ ์„œ๋ธ”๋ฆฟ ๋งŒ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉ์ ์ด๋‹ค.
์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์€ ๊ฐ์ฒด๋ฅผ ๋‹จ ํ•˜๋‚˜๋งŒ ์ƒ์ƒํ•ด์„œ ๊ณต์œ ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ƒ์„ฑ์ž๋ฅผ private ์ ‘๊ทผ์ž๋กœ ๋ง‰์•„๋‘”๋‹ค.

 

ํšŒ์› ์ €์žฅ์†Œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

class MemberRepositoryTest {
  
  MemberRepository memberRepository = MemberRepository.getInstance();
  
  @AfterEach
  void afterEach() {
    memberRepository.clearStore();
  }

  @Test
  void save() {
    //given
    Member member = new Member("hello", 20);
    //when
    Member savedMember = memberRepository.save(member);
    //then
    Member findMember = memberRepository.findById(savedMember.getId());
    assertThat(findMember).isEqualTo(savedMember);
  }
  
  @Test
  void findAll() {
    //given
    Member member1 = new Member("member1", 20);
    Member member2 = new Member("member2", 30);
    memberRepository.save(member1);
    memberRepository.save(member2);
    //when
    List<Member> result = memberRepository.findAll();
    //then
    assertThat(result.size()).isEqualTo(2);
    assertThat(result).contains(member1, member2);
  }
  
}

2. ์„œ๋ธ”๋ฆฟ์œผ๋กœ ํšŒ์› ๊ด€๋ฆฌ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งŒ๋“ค๊ธฐ

์„œ๋ธ”๋ฆฟ์œผ๋กœ ํšŒ์› ๋“ฑ๋ก HTML form ์ œ๊ณต

WebServlet(name = "memberFormServlet", urlPatterns = "/servlet/members/new-form")
public class MemberFormServlet extends HttpServlet {
  
  @Override
  protected void service(HttpServletRequest request, HttpServletResponse response)
              throws ServletException, IOException {
    response.setContentType("text/html");
    response.setCharacterEncoding("utf-8");
    PrintWriter w = response.getWriter();
    w.write("<!DOCTYPE html>\n" +
"<html>\n" +
"<head>\n" +
"    <meta charset=\"UTF-8\">\n" +
"    <title>Title</title>\n" +
"</head>\n" +
"<body>\n" +
"<form action=\"/servlet/members/save\" method=\"post\">\n" +
"    username: <input type=\"text\" name=\"username\" />\n" +
"    age:      <input type=\"text\" name=\"age\" />\n" +
" <button type=\"submit\">์ „์†ก</button>\n" + "</form>\n" +
"</body>\n" +
"</html>\n");

  }
}

ํšŒ์› ์ €์žฅ

@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");
    
    String username = request.getParameter("username");
    int age = Integer.parseInt(request.getParameter("age"));
    
    Member member = new Member(username, age);
    System.out.println("member = " + member);
    memberRepository.save(member);
    
    response.setContentType("text/html");
    response.setCharacterEncoding("utf-8");
    
    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>");
  }
}
MemberSaveServlet ์€ ๋‹ค์Œ ์ˆœ์„œ๋กœ ๋™์ž‘ํ•œ๋‹ค.
1. ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์กฐํšŒํ•ด์„œ Member ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค.
2. Member ๊ฐ์ฒด๋ฅผ MemberRepository๋ฅผ ํ†ตํ•ด์„œ ์ €์žฅํ•œ๋‹ค.
3. Member ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฒฐ๊ณผ ํ™”๋ฉด์šฉ HTML์„ ๋™์ ์œผ๋กœ ๋งŒ๋“ค์–ด์„œ ์‘๋‹ตํ•œ๋‹ค.

 

๋ชจ๋“  ํšŒ์› ๋ชฉ๋ก ์กฐํšŒ

@WebServlet(name = "memberListServlet", urlPatterns = "/servlet/members")
public class MemberListServlet extends HttpServlet {

  private MemberRepository memberRepository = MemberRepository.getInstance();
  
  @Override
  protected void service(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException {

    response.setContentType("text/html");
    response.setCharacterEncoding("utf-8");
    
    List<Member> members = memberRepository.findAll();
    
    PrintWriter w = response.getWriter();
    w.write("<html>");
    w.write("<head>");
    w.write("    <meta charset=\"UTF-8\">");
    w.write("    <title>Title</title>");
    w.write("</head>");
    w.write("<body>");
    w.write("<a href=\"/index.html\">๋ฉ”์ธ</a>");
    w.write("<table>");
    w.write("    <thead>");
    w.write("    <th>id</th>");
    w.write("    <th>username</th>");
    w.write("    <th>age</th>");
    w.write("    </thead>");
    w.write("    <tbody>");

    for (Member member : members) {
      w.write("    <tr>");
      w.write("        <td>" + member.getId() + "</td>");
      w.write("        <td>" + member.getUsername() + "</td>");
      w.write("        <td>" + member.getAge() + "</td>");
      w.write("    </tr>");
    }
    
    w.write("    </tbody>");
    w.write("</table>");
    w.write("</body>");
    w.write("</html>");
  } 
}
MemberListServlet ์€ ๋‹ค์Œ ์ˆœ์„œ๋กœ ๋™์ž‘ํ•œ๋‹ค.
1. memberRepository.findAll() ์„ ํ†ตํ•ด ๋ชจ๋“  ํšŒ์›์„ ์กฐํšŒํ•œ๋‹ค.
2. ํšŒ์› ๋ชฉ๋ก HTML์„ for ๋ฃจํ”„๋ฅผ ํ†ตํ•ด์„œ ํšŒ์› ์ˆ˜ ๋งŒํผ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜๊ณ  ์‘๋‹ตํ•œ๋‹ค.

 

ํ…œํ”Œ๋ฆฟ ์—”์ง„์œผ๋กœ
์ง€๊ธˆ๊นŒ์ง€ ์„œ๋ธ”๋ฆฟ๊ณผ ์ž๋ฐ” ์ฝ”๋“œ๋งŒ์œผ๋กœ HTML์„ ๋งŒ๋“ค์–ด๋ณด์•˜๋‹ค.
์„œ๋ธ”๋ฆฟ ๋•๋ถ„์— ๋™์ ์œผ๋กœ ์›ํ•˜๋Š” HTML์„ ๋งˆ์Œ๊ป ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
์ •์ ์ธ HTML ๋ฌธ์„œ๋ผ๋ฉด ํ™”๋ฉด์ด ๊ณ„์† ๋‹ฌ๋ผ์ง€๋Š” ํšŒ์›์˜ ์ €์žฅ ๊ฒฐ๊ณผ๋ผ๋˜๊ฐ€, ํšŒ์› ๋ชฉ๋ก ๊ฐ™์€ ๋™์ ์ธ HTML์„ ๋งŒ๋“œ๋Š” ์ผ์€ ๋ถˆ๊ฐ€๋Šฅ ํ•  ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿฐ๋ฐ
, ์ฝ”๋“œ์—์„œ ๋ณด๋“ฏ์ด ์ด๊ฒƒ์€ ๋งค์šฐ ๋ณต์žกํ•˜๊ณ  ๋น„ํšจ์œจ ์ ์ด๋‹ค.
์ž๋ฐ” ์ฝ”๋“œ๋กœ HTML์„ ๋งŒ๋“ค์–ด ๋‚ด๋Š” ๊ฒƒ ๋ณด๋‹ค ์ฐจ๋ผ๋ฆฌ HTML ๋ฌธ์„œ์— ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ๋ถ€๋ถ„๋งŒ ์ž๋ฐ” ์ฝ”๋“œ๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋” ํŽธ๋ฆฌํ•  ๊ฒƒ์ด๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ ํ…œํ”Œ๋ฆฟ ์—”์ง„์ด ๋‚˜์˜จ ์ด์œ ์ด๋‹ค.
ํ…œํ”Œ๋ฆฟ ์—”์ง„์„ ์‚ฌ์šฉํ•˜๋ฉด HTML ๋ฌธ์„œ์—์„œ ํ•„์š”ํ•œ ๊ณณ๋งŒ ์ฝ”๋“œ๋ฅผ ์ ์šฉํ•ด์„œ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ…œํ”Œ๋ฆฟ ์—”์ง„์—๋Š” JSP, Thymeleaf, Freemarker, Velocity๋“ฑ์ด ์žˆ๋‹ค.
๋‹ค์Œ ์‹œ๊ฐ„์—๋Š” JSP๋กœ ๋™์ผํ•œ ์ž‘์—…์„ ์ง„ํ–‰ํ•ด๋ณด์ž.

3. JSP๋กœ ํšŒ์› ๊ด€๋ฆฌ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งŒ๋“ค๊ธฐ

๊ธฐ๋ณธ ์„ค์ •ํ•˜๊ธฐ (๊ต์žฌ ํ™•์ธ)

 

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

<%@ page contentType="text/html;charset=UTF-8" language="java" %> // JSP ๋ฌธ์„œ๋ผ๋Š” ๋œป
<html>
  <head>
    <title>Title</title>
  </head>
  <body>
    <form action="/jsp/members/save.jsp" method="post">
      username: <input type="text" name="username" />
      age: <input type="text" name="age" /> <button type="submit">์ „์†ก</button>
    </form>
  </body>
</html>

 

ํšŒ์› ์ €์žฅ JSP

<%@ page import="hello.servlet.domain.member.MemberRepository" %>
<%@ page import="hello.servlet.domain.member.Member" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
  // request, response ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  
  MemberRepository memberRepository = MemberRepository.getInstance();
  
  System.out.println("save.jsp");
  String username = request.getParameter("username");
  int age = Integer.parseInt(request.getParameter("age"));
  
  Member member = new Member(username, age);
  System.out.println("member = " + member);
  memberRepository.save(member);
  
%>

<html>
  <head>
      <meta charset="UTF-8">
  </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>

* ์ž๋ฐ” ์ฝ”๋“œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

<%@ page import="hello.servlet.domain.member.MemberRepository" %>

<% ~~ %>    :   ์ž๋ฐ” ์ฝ”๋“œ ์ž…๋ ฅ ๊ฐ€๋Šฅ

<%= ~~ %>  :   ์ž๋ฐ” ์ฝ”๋“œ ์ถœ๋ ฅ ๊ฐ€๋Šฅ

ํšŒ์› ์ €์žฅ JSP๋ฅผ ๋ณด๋ฉด, ํšŒ์› ์ €์žฅ ์„œ๋ธ”๋ฆฟ ์ฝ”๋“œ์™€ ๊ฐ™๋‹ค.
๋‹ค๋ฅธ ์ ์ด ์žˆ๋‹ค๋ฉด, HTML์„ ์ค‘์‹ฌ์œผ๋กœ ํ•˜๊ณ , ์ž๋ฐ”
์ฝ”๋“œ๋ฅผ ๋ถ€๋ถ„๋ถ€๋ถ„ ์ž…๋ ฅํ•ด์ฃผ์—ˆ๋‹ค.
<% ~ %> ๋ฅผ ์‚ฌ์šฉํ•ด์„œ HTML ์ค‘๊ฐ„์— ์ž๋ฐ” ์ฝ”๋“œ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ์žˆ๋‹ค.

 

ํšŒ์› ๋ชฉ๋ก JSP

<%@ 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(" <td> " + member.getId() + "</td>");
        out.write(" <td> " + member.getUsername() + "</td>");
        out.write(" <td> " + member.getAge() + "</td>");
        out.write("    </tr>");
     } 
%>
      </tbody>
  </table>
  </body>
  </html>

ํšŒ์› ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ๋จผ์ € ์กฐํšŒํ•˜๊ณ ,

๊ฒฐ๊ณผ List๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ค‘๊ฐ„์— <tr><td> HTML ํƒœ๊ทธ๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ์ถœ๋ ฅํ•˜๊ณ  ์žˆ๋‹ค.

 

์„œ๋ธ”๋ฆฟ๊ณผ JSP์˜ ํ•œ๊ณ„

์„œ๋ธ”๋ฆฟ์œผ๋กœ ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” ๋ทฐ(View)ํ™”๋ฉด์„ ์œ„ํ•œ HTML์„ ๋งŒ๋“œ๋Š” ์ž‘์—…์ด ์ž๋ฐ” ์ฝ”๋“œ์— ์„ž์—ฌ์„œ ์ง€์ €๋ถ„ํ•˜๊ณ  ๋ณต์žกํ–ˆ๋‹ค.
JSP
๋ฅผ ์‚ฌ์šฉํ•œ ๋•๋ถ„์— ๋ทฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” HTML ์ž‘์—…์„ ๊น”๋”ํ•˜๊ฒŒ ๊ฐ€์ ธ๊ฐ€๊ณ , ์ค‘๊ฐ„์ค‘๊ฐ„ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์—๋งŒ ์ž๋ฐ” ์ฝ”๋“œ๋ฅผ ์ ์šฉํ–ˆ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ ์ด๋ ‡๊ฒŒ ํ•ด๋„ ํ•ด๊ฒฐ๋˜์ง€ ์•Š๋Š” ๋ช‡๊ฐ€์ง€ ๊ณ ๋ฏผ์ด ๋‚จ๋Š”๋‹ค.

ํšŒ์› ์ €์žฅ JSP๋ฅผ ๋ณด์ž.
์ฝ”๋“œ์˜ ์ƒ์œ„ ์ ˆ๋ฐ˜์€ ํšŒ์›์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด๊ณ , ๋‚˜๋จธ์ง€ ํ•˜์œ„ ์ ˆ๋ฐ˜๋งŒ ๊ฒฐ๊ณผ๋ฅผ HTML๋กœ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•œ ๋ทฐ ์˜์—ญ์ด๋‹ค.
ํšŒ์› ๋ชฉ๋ก์˜ ๊ฒฝ์šฐ์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋‹ค.

์ฝ”๋“œ๋ฅผ ์ž˜ ๋ณด๋ฉด, JAVA ์ฝ”๋“œ, ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๋“ฑ๋“ฑ ๋‹ค์–‘ํ•œ ์ฝ”๋“œ๊ฐ€ ๋ชจ๋‘ JSP์— ๋…ธ์ถœ๋˜์–ด ์žˆ๋‹ค.
JSP
๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์€ ์—ญํ• ์„ ํ•œ๋‹ค.
์ด๋ ‡๊ฒŒ ์ž‘์€ ํ”„๋กœ์ ํŠธ๋„ ๋ฒŒ์จ ๋จธ๋ฆฌ๊ฐ€ ์•„ํŒŒ์˜ค๋Š”๋ฐ, ์ˆ˜๋ฐฑ ์ˆ˜์ฒœ์ค„์ด ๋„˜์–ด๊ฐ€๋Š” JSP๋ฅผ ๋– ์˜ฌ๋ ค๋ณด๋ฉด ์ •๋ง ์ง€์˜ฅ๊ณผ ๊ฐ™์„ ๊ฒƒ์ด๋‹ค. (์œ ์ง€๋ณด์ˆ˜ ์ง€์˜ฅ)

MVC ํŒจํ„ด์˜ ๋“ฑ์žฅ
๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ์„œ๋ธ”๋ฆฟ ์ฒ˜๋Ÿผ ๋‹ค๋ฅธ๊ณณ์—์„œ ์ฒ˜๋ฆฌํ•˜๊ณ , JSP๋Š” ๋ชฉ์ ์— ๋งž๊ฒŒ HTML๋กœ ํ™”๋ฉด(View)์„ ๊ทธ๋ฆฌ๋Š” ์ผ์— ์ง‘์ค‘


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

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

- ํ•˜๋‚˜์˜ ์„œ๋ธ”๋ฆฟ/JSP -> ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง + ๋ทฐ ๋ Œ๋”๋ง

- ์œ ์ง€๋ณด์ˆ˜ ์–ด๋ ค์›Œ์ง

 

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

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

 

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

- JSP (๋ทฐ ํ…œํ”Œ๋ฆฟ) -> ํ™”๋ฉด ๋ Œ๋”๋ง ์ตœ์ ํ™” (์—ฌ๊ธฐ์— ์ง‘์ค‘)

 

MVC (Model View Controller)

- ์„œ๋ธ”๋ฆฟ์ด๋‚˜ JSP๋กœ ์ฒ˜๋ฆฌํ•˜๋˜ ๊ฒƒ์„ ์ปจํŠธ๋กค๋Ÿฌ(Controller)์™€ ๋ทฐ(View)๋กœ ์—ญํ•  ๋‚˜๋ˆˆ ๊ฒƒ

- ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋ณดํ†ต MVC ํŒจํ„ด ์‚ฌ์šฉ

 

[๋ชจ๋ธ]

- ๋ทฐ์— ์ถœ๋ ฅํ•  ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๊ณ  ์ „๋‹ฌํ•ด์ฃผ๋Š” ์—ญํ• 

- ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด๋‚˜ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผ ๋ชฐ๋ผ๋„ ๋˜๊ณ  ํ™”๋ฉด ๋ Œ๋”๋ง์— ์ง‘์ค‘ ๊ฐ€๋Šฅ

 

[๋ทฐ]

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

- HTML ์ƒ์„ฑ ๋ถ€๋ถ„

 

[์ปจํŠธ๋กค๋Ÿฌ]

- HTTP ์š”์ฒญ์„ ๋ฐ›์•„ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฒ€์ฆ + ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์‹คํ–‰

- ๋ทฐ์— ์ „๋‹ฌํ•  ๊ฒฐ๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•ด์„œ ๋ชจ๋ธ์— ๋‹ด์Œ

 

์ฐธ๊ณ ) 

์ปจํŠธ๋กค๋Ÿฌ์— ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋‘˜ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ปจํŠธ๋กค๋Ÿฌ ๋ถ€๋‹ด ๋งŽ์•„์ง

๊ทธ๋ž˜์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ์„œ๋น„์Šค(Service)๊ณ„์ธต์—์„œ ์ฒ˜๋ฆฌ

์ปจํŠธ๋กค๋Ÿฌ๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์žˆ๋Š” ์„œ๋น„์Šค๋ฅผ ํ˜ธ์ถœ

๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋ณ€๊ฒฝ -> ์ปจํŠธ๋กค๋Ÿฌ ์ฝ”๋“œ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Œ

 

MVC ํŒจํ„ด 1

 

 

MVC ํŒจํ„ด 2


5. MVC ํŒจํ„ด - ์ ์šฉ

์„œ๋ธ”๋ฆฟ์„ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์‚ฌ์šฉํ•˜๊ณ , JSP๋ฅผ ๋ทฐ๋กœ ์‚ฌ์šฉํ•ด์„œ MVC ํŒจํ„ด์„ ์ ์šฉ
Model
์€ HttpServletRequest ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
request
๋Š” ๋‚ด๋ถ€์— ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ, request.setAttribute() , request.getAttribute() ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๊ด€ํ•˜๊ณ ,
์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํšŒ์› ๋“ฑ๋ก

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

@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๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. ์„œ๋ฒ„ ๋‚ด๋ถ€์—์„œ ๋‹ค์‹œ ํ˜ธ์ถœ์ด ๋ฐœ์ƒ

* ์ด ๊ฒฝ๋กœ์•ˆ์— JSP๊ฐ€ ์žˆ์œผ๋ฉด ์™ธ๋ถ€์—์„œ ์ง์ ‘ JSP๋ฅผ ๋ถˆ๊ฐ€ / ์šฐ๋ฆฌ๊ฐ€ ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฒƒ์€ ํ•ญ์ƒ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ†ตํ•ด์„œ JSP๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ

redirect VS forward

[๋ฆฌ๋‹ค์ด๋ ‰ํŠธ]๋Š” ์‹ค์ œ ํด๋ผ์ด์–ธํŠธ(์›น ๋ธŒ๋ผ์šฐ์ €)์— ์‘๋‹ต์ด ๋‚˜๊ฐ”๋‹ค๊ฐ€, ํด๋ผ์ด์–ธํŠธ๊ฐ€ redirect ๊ฒฝ๋กœ๋กœ ๋‹ค์‹œ ์š”์ฒญ
๋”ฐ๋ผ์„œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ๊ณ , URL ๊ฒฝ๋กœ๋„ ์‹ค์ œ๋กœ ๋ณ€๊ฒฝ (ํ˜ธ์ถœ์ด ๋‘๋ฒˆ ์ผ์–ด๋‚จ)

๋ฐ˜๋ฉด ํฌ์›Œ๋“œ๋Š” ์„œ๋ฒ„ ๋‚ด๋ถ€์—์„œ ์ผ์–ด๋‚˜๋Š” ํ˜ธ์ถœ์ด๊ธฐ ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ „ํ˜€ ์ธ์ง€ํ•˜์ง€ ๋ชปํ•œ๋‹ค. (์„œ๋ฒ„ ๋‚ด๋ถ€์—์„œ ํ•จ์ˆ˜ ํ˜ธ์ถœ ํ•˜๋“ฏ์ด)

 

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

<%@ 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 ํ˜ธ์ถœ

ex)

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

๊ฒฐ๊ณผ : '/servlet-mvc/members/save'

 

ํšŒ์› ์ €์žฅ

 

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

@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);
    System.out.println("member = " + member);
    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);
  } 
}

 

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

<%@ 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>

 

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

 

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

@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 {
    System.out.println("MvcMemberListServlet.service");
    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);
  } 
}

- request ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ชจ๋ธ์— ์ €์žฅ

 

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

<%@ 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>

- c: forEach = jstl ๋ฌธ๋ฒ•

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

5. MVC ํŒจํ„ด - ํ•œ๊ณ„

MVC ํŒจํ„ด์„ ์ ์šฉํ•œ ๋•๋ถ„์— ์ปจํŠธ๋กค๋Ÿฌ์˜ ์—ญํ• ๊ณผ ๋ทฐ๋ฅผ ๋ Œ๋”๋ง ํ•˜๋Š” ์—ญํ• ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.
ํŠนํžˆ ๋ทฐ๋Š” ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๋Š” ์—ญํ• ์— ์ถฉ์‹คํ•œ ๋•๋ถ„์—, ์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•˜๊ณ  ์ง๊ด€์ ์ด๋‹ค.
๋‹จ์ˆœํ•˜๊ฒŒ ๋ชจ๋ธ์—์„œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊บผ๋‚ด๊ณ , ํ™”๋ฉด์„ ๋งŒ๋“ค๋ฉด ๋œ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ๋”ฑ ๋ด๋„ ์ค‘๋ณต์ด ๋งŽ๊ณ , ํ•„์š”ํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋“ค๋„ ๋งŽ์ด ๋ณด์ธ๋‹ค

 

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

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

 - View๋กœ ์ด๋™ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ํ•ญ์ƒ ์ค‘๋ณต ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•œ๋‹ค.

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

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

 

2) ViewPath์— ์ค‘๋ณต

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

prefix & suffix

-> ๋งŒ์•ฝ jsp์—์„œ thymeleaf ๋ทฐ๋กœ ๋ณ€๊ฒฝ๋˜๋ฉด ์ „์ฒด ์ฝ”๋“œ ๋‹ค ๋ณ€๊ฒฝํ•ด์•ผํ•จ

 

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

  HttpServletRequest request, HttpServletResponse response

- ํ˜„์žฌ ์˜ˆ์‹œ์—์„œ reponse ์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ

 

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

- ๊ธฐ๋Šฅ ๋ณต์žกํ•ด์งˆ์ˆ˜๋ก ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๊ณตํ†ต์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๋Š” ๋ถ€๋ถ„ ๋Š˜์–ด๋‚จ

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

 

[์ •๋ฆฌ]

๊ณตํ†ต ์ฒ˜๋ฆฌ ์–ด๋ ค์›€

-> ๊ณตํ†ต ๊ธฐ๋Šฅ ์ฒ˜๋ฆฌ (์ˆ˜๋ฌธ์žฅ ์—ญํ• )

-> Front Controller (ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ) ํŒจํ„ด์œผ๋กœ ํ•ด๊ฒฐ (ํ•ต์‹ฌ)

  • ๋„ค์ด๋ฒ„ ๋ธ”๋Ÿฌ๊ทธ ๊ณต์œ ํ•˜๊ธฐ
  • ๋„ค์ด๋ฒ„ ๋ฐด๋“œ์— ๊ณต์œ ํ•˜๊ธฐ
  • ํŽ˜์ด์Šค๋ถ ๊ณต์œ ํ•˜๊ธฐ
  • ์นด์นด์˜ค์Šคํ† ๋ฆฌ ๊ณต์œ ํ•˜๊ธฐ