쌓고 쌓다

서블릿, JSP로 MVC 패턴 만들기 본문

프로그래밍/JSP & Servlet

서블릿, JSP로 MVC 패턴 만들기

승민아 2023. 7. 29. 18:16

서블릿은 Controller로, JSP는 View로 사용한다.

Model은 HttpServletRequest 객체를 사용한다.

 

회원 저장

formController

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

*WEB-INF에 있는것은 Controller를 통해서만 접근이 가능하다. URL로 접근 안된다.

 

forward

서버 내부에서 다시 호출하기 때문에 클라이언트는 인식할 수 없고 URL도 변경되지 않는다. 호출이 1번 일어남.

redirect

응답이 클라이언트에게 갔다가, 클라이언트가 다시 redirect 경로로 요청을 보낸다. 호출이 2번 일어남.

클라이언트가 인식할 수 있고 URL 또한 변경된다.

 

URL은 new-form 요청이지만 new-form.jsp 페이지를 응답 받았다.

 

new-form.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <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>

action 경로가 save이다. 

이것은 상대경로 위치로 현재 URL 경로에서 save를 호출한다. (현재 경로: /servlet-mvc/memvers/)

만약 상대 경로라면 action 경로를 "/servlet-mvc/members/save"로 지정한다.

 

saveController

@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")); // request.getParameter의 반환은 문자열이다. 변환 필요.

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

        request.setAttribute("member", member);

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

form 데이터로 넘어온 POST 요청을 getParameter로 꺼낸다. URL 쿼리 파라미터와 형식이 같기에 getParameter로 꺼낼 수 있다.

받은 데이터를 Repository에 저장하고 Model에 담아 save-result.jsp로 응답한다.

 

Model은 HttpServletRequest 객체를 사용하며 아래의 방법으로 데이터를 저장하고 꺼낸다.

  • request.setAttribute() : 데이터 저장
  • request.getAttribute() : 데이터 조회

 

save-result.jsp

<%@ page import="hello.servlet.domain.member.Member" %> <!-- 프로퍼티 접근법 사용시 import 필요 없음  -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<ul>
    <li>id = <%=((Member) request.getAttribute("member")).getId()%>
    </li>
    <li>username = <%=((Member) request.getAttribute("member")).getUsername()%>
    </li>
    <li>age = <%=((Member) request.getAttribute("member")).getAge()%>
    </li>

    <!-- 프로퍼티 접근법 또한 가능 -->
    <li>id = ${member.id}</li>
    <li>username = ${member.username}</li>
    <li>age = ${member.age}</li>
</ul>
<a href="/index.html">메인</a>
</body>
</html>

Model에 담긴 데이터는 프로퍼티 접근법으로 ${member.id}처럼 접근하자. JSP가 ${} 문법을 제공하는 것이다.

 

회원 목록

memberListController

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

멤버 목록 또한 마찬가지로 List<Member>를 request를 통해 Model에 담아주면 된다.

 

members.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!-- JSP가 태그를 생성해줌 -->
<html>
<head>
    <title>Title</title>
</head>
<body>
<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>

JSP가 제공하는 JSTL로 HTML 표준 태그를 생성할 수 있다.

<c:forEach> 기능으로 members에 담긴 데이터를 하나씩 뽑아 태그를 생성.

사용시 아래의 선언이 필요하다.

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

 

MVC 패턴 한계

MVC 패턴에서 각 요청마다 각 Controller가 담당한다.

즉, 모든 컨트롤러에서 공통 처리하는 기능을 만들기가 어렵다.

프론트 컨트롤러로 컨트롤러 호출전에 공통 기능을 처리할 수 있다.

 

'프로그래밍 > JSP & Servlet' 카테고리의 다른 글

프론트 컨트롤러 개념과 구현  (0) 2023.07.30
JSP 애플리케이션과 MVC 패턴  (0) 2023.07.25
서블릿 애플리케이션과 템플릿 엔진  (0) 2023.07.24
HTTP 응답 데이터  (0) 2023.07.22
HTTP 요청 데이터  (0) 2023.07.20
Comments